diff --git a/Application/Common/Exceptions/NotFoundException.cs b/Application/Common/Exceptions/NotFoundException.cs
new file mode 100644
index 0000000..c310b74
--- /dev/null
+++ b/Application/Common/Exceptions/NotFoundException.cs
@@ -0,0 +1,10 @@
+using System;
+using System.Reflection;
+
+namespace Mirea.Api.DataAccess.Application.Common.Exceptions;
+
+public class NotFoundException : Exception
+{
+ public NotFoundException(MemberInfo entity, string name, object id) : base($"The entity \"{entity.Name}\" property \"{name}\" was not found by id \"{id}\".") { }
+ public NotFoundException(MemberInfo entity, object id) : base($"The entity \"{entity.Name}\" was not found by id \"{id}\".") { }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Campus/Queries/GetCampusBasicInfoList/CampusBasicInfoDto.cs b/Application/Cqrs/Campus/Queries/GetCampusBasicInfoList/CampusBasicInfoDto.cs
new file mode 100644
index 0000000..e0c9918
--- /dev/null
+++ b/Application/Cqrs/Campus/Queries/GetCampusBasicInfoList/CampusBasicInfoDto.cs
@@ -0,0 +1,22 @@
+namespace Mirea.Api.DataAccess.Application.Cqrs.Campus.Queries.GetCampusBasicInfoList;
+
+///
+/// Represents basic information about a campus.
+///
+public class CampusBasicInfoDto
+{
+ ///
+ /// The unique identifier for the campus.
+ ///
+ public int Id { get; set; }
+
+ ///
+ /// The code name associated with the campus.
+ ///
+ public required string CodeName { get; set; }
+
+ ///
+ /// The full name of the campus.
+ ///
+ public string? FullName { get; set; }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Campus/Queries/GetCampusBasicInfoList/CampusBasicInfoVm.cs b/Application/Cqrs/Campus/Queries/GetCampusBasicInfoList/CampusBasicInfoVm.cs
new file mode 100644
index 0000000..a3a5f2d
--- /dev/null
+++ b/Application/Cqrs/Campus/Queries/GetCampusBasicInfoList/CampusBasicInfoVm.cs
@@ -0,0 +1,14 @@
+using System.Collections.Generic;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Campus.Queries.GetCampusBasicInfoList;
+
+///
+/// Represents a view model containing basic information about multiple campuses.
+///
+public class CampusBasicInfoVm
+{
+ ///
+ /// The list of campus basic information.
+ ///
+ public IList Campuses { get; set; } = new List();
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Campus/Queries/GetCampusBasicInfoList/GetCampusBasicInfoListQuery.cs b/Application/Cqrs/Campus/Queries/GetCampusBasicInfoList/GetCampusBasicInfoListQuery.cs
new file mode 100644
index 0000000..2059735
--- /dev/null
+++ b/Application/Cqrs/Campus/Queries/GetCampusBasicInfoList/GetCampusBasicInfoListQuery.cs
@@ -0,0 +1,5 @@
+using MediatR;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Campus.Queries.GetCampusBasicInfoList;
+
+public class GetCampusBasicInfoListQuery : IRequest;
\ No newline at end of file
diff --git a/Application/Cqrs/Campus/Queries/GetCampusBasicInfoList/GetCampusBasicInfoListQueryHandler.cs b/Application/Cqrs/Campus/Queries/GetCampusBasicInfoList/GetCampusBasicInfoListQueryHandler.cs
new file mode 100644
index 0000000..3cd6259
--- /dev/null
+++ b/Application/Cqrs/Campus/Queries/GetCampusBasicInfoList/GetCampusBasicInfoListQueryHandler.cs
@@ -0,0 +1,26 @@
+using MediatR;
+using Microsoft.EntityFrameworkCore;
+using Mirea.Api.DataAccess.Application.Interfaces.DbContexts.Schedule;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Campus.Queries.GetCampusBasicInfoList;
+
+public class GetCampusBasicInfoListQueryHandler(ICampusDbContext dbContext) : IRequestHandler
+{
+ public async Task Handle(GetCampusBasicInfoListQuery request, CancellationToken cancellationToken)
+ {
+ var dtos = await dbContext.Campuses.Select(c => new CampusBasicInfoDto()
+ {
+ Id = c.Id,
+ CodeName = c.CodeName,
+ FullName = c.FullName
+ }).ToListAsync(cancellationToken);
+
+ return new CampusBasicInfoVm
+ {
+ Campuses = dtos
+ };
+ }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Campus/Queries/GetCampusDetails/CampusDetailsVm.cs b/Application/Cqrs/Campus/Queries/GetCampusDetails/CampusDetailsVm.cs
new file mode 100644
index 0000000..35246c1
--- /dev/null
+++ b/Application/Cqrs/Campus/Queries/GetCampusDetails/CampusDetailsVm.cs
@@ -0,0 +1,27 @@
+namespace Mirea.Api.DataAccess.Application.Cqrs.Campus.Queries.GetCampusDetails;
+
+///
+/// Represents a view model containing detailed information about a campus.
+///
+public class CampusDetailsVm
+{
+ ///
+ /// The unique identifier for the campus.
+ ///
+ public int Id { get; set; }
+
+ ///
+ /// The code name associated with the campus.
+ ///
+ public required string CodeName { get; set; }
+
+ ///
+ /// The full name of the campus.
+ ///
+ public string? FullName { get; set; }
+
+ ///
+ /// The address of the campus.
+ ///
+ public string? Address { get; set; }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Campus/Queries/GetCampusDetails/GetCampusDetailsQuery.cs b/Application/Cqrs/Campus/Queries/GetCampusDetails/GetCampusDetailsQuery.cs
new file mode 100644
index 0000000..8609b18
--- /dev/null
+++ b/Application/Cqrs/Campus/Queries/GetCampusDetails/GetCampusDetailsQuery.cs
@@ -0,0 +1,8 @@
+using MediatR;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Campus.Queries.GetCampusDetails;
+
+public class GetCampusDetailsQuery : IRequest
+{
+ public required int Id { get; set; }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Campus/Queries/GetCampusDetails/GetCampusDetailsQueryHandler.cs b/Application/Cqrs/Campus/Queries/GetCampusDetails/GetCampusDetailsQueryHandler.cs
new file mode 100644
index 0000000..75af510
--- /dev/null
+++ b/Application/Cqrs/Campus/Queries/GetCampusDetails/GetCampusDetailsQueryHandler.cs
@@ -0,0 +1,24 @@
+using MediatR;
+using Microsoft.EntityFrameworkCore;
+using Mirea.Api.DataAccess.Application.Common.Exceptions;
+using Mirea.Api.DataAccess.Application.Interfaces.DbContexts.Schedule;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Campus.Queries.GetCampusDetails;
+
+public class GetCampusDetailsQueryHandler(ICampusDbContext dbContext) : IRequestHandler
+{
+ public async Task Handle(GetCampusDetailsQuery request, CancellationToken cancellationToken)
+ {
+ var campus = await dbContext.Campuses.FirstOrDefaultAsync(c => c.Id == request.Id, cancellationToken) ?? throw new NotFoundException(typeof(Domain.Schedule.Campus), request.Id);
+
+ return new CampusDetailsVm()
+ {
+ Id = campus.Id,
+ CodeName = campus.CodeName,
+ FullName = campus.FullName,
+ Address = campus.Address
+ };
+ }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Discipline/Queries/GetDisciplineDetails/DisciplineInfoVm.cs b/Application/Cqrs/Discipline/Queries/GetDisciplineDetails/DisciplineInfoVm.cs
new file mode 100644
index 0000000..c6ac1b1
--- /dev/null
+++ b/Application/Cqrs/Discipline/Queries/GetDisciplineDetails/DisciplineInfoVm.cs
@@ -0,0 +1,17 @@
+namespace Mirea.Api.DataAccess.Application.Cqrs.Discipline.Queries.GetDisciplineDetails;
+
+///
+/// Represents disciplines.
+///
+public class DisciplineInfoVm
+{
+ ///
+ /// The unique identifier for the discipline.
+ ///
+ public int Id { get; set; }
+
+ ///
+ /// The name of the discipline.
+ ///
+ public required string Name { get; set; }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Discipline/Queries/GetDisciplineDetails/GetDisciplineInfoQuery.cs b/Application/Cqrs/Discipline/Queries/GetDisciplineDetails/GetDisciplineInfoQuery.cs
new file mode 100644
index 0000000..b6c0621
--- /dev/null
+++ b/Application/Cqrs/Discipline/Queries/GetDisciplineDetails/GetDisciplineInfoQuery.cs
@@ -0,0 +1,8 @@
+using MediatR;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Discipline.Queries.GetDisciplineDetails;
+
+public class GetDisciplineInfoQuery : IRequest
+{
+ public required int Id { get; set; }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Discipline/Queries/GetDisciplineDetails/GetDisciplineInfoQueryHandler.cs b/Application/Cqrs/Discipline/Queries/GetDisciplineDetails/GetDisciplineInfoQueryHandler.cs
new file mode 100644
index 0000000..007e74f
--- /dev/null
+++ b/Application/Cqrs/Discipline/Queries/GetDisciplineDetails/GetDisciplineInfoQueryHandler.cs
@@ -0,0 +1,22 @@
+using MediatR;
+using Microsoft.EntityFrameworkCore;
+using Mirea.Api.DataAccess.Application.Common.Exceptions;
+using Mirea.Api.DataAccess.Application.Interfaces.DbContexts.Schedule;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Discipline.Queries.GetDisciplineDetails;
+
+public class GetDisciplineInfoQueryHandler(IDisciplineDbContext dbContext) : IRequestHandler
+{
+ public async Task Handle(GetDisciplineInfoQuery request, CancellationToken cancellationToken)
+ {
+ var discipline = await dbContext.Disciplines.FirstOrDefaultAsync(d => d.Id == request.Id, cancellationToken) ?? throw new NotFoundException(typeof(Domain.Schedule.Discipline), request.Id);
+
+ return new DisciplineInfoVm()
+ {
+ Id = discipline.Id,
+ Name = discipline.Name,
+ };
+ }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Discipline/Queries/GetDisciplineList/DisciplineListVm.cs b/Application/Cqrs/Discipline/Queries/GetDisciplineList/DisciplineListVm.cs
new file mode 100644
index 0000000..3f5c835
--- /dev/null
+++ b/Application/Cqrs/Discipline/Queries/GetDisciplineList/DisciplineListVm.cs
@@ -0,0 +1,14 @@
+using System.Collections.Generic;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Discipline.Queries.GetDisciplineList;
+
+///
+/// Represents a view model containing multiple disciplines name.
+///
+public class DisciplineListVm
+{
+ ///
+ /// The list of disciplines.
+ ///
+ public IList Disciplines { get; set; } = new List();
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Discipline/Queries/GetDisciplineList/DisciplineLookupDto.cs b/Application/Cqrs/Discipline/Queries/GetDisciplineList/DisciplineLookupDto.cs
new file mode 100644
index 0000000..0a090df
--- /dev/null
+++ b/Application/Cqrs/Discipline/Queries/GetDisciplineList/DisciplineLookupDto.cs
@@ -0,0 +1,17 @@
+namespace Mirea.Api.DataAccess.Application.Cqrs.Discipline.Queries.GetDisciplineList;
+
+///
+/// Represents disciplines.
+///
+public class DisciplineLookupDto
+{
+ ///
+ /// The unique identifier for the discipline.
+ ///
+ public int Id { get; set; }
+
+ ///
+ /// The name of the discipline.
+ ///
+ public required string Name { get; set; }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Discipline/Queries/GetDisciplineList/GetDisciplineListQuery.cs b/Application/Cqrs/Discipline/Queries/GetDisciplineList/GetDisciplineListQuery.cs
new file mode 100644
index 0000000..f3b770b
--- /dev/null
+++ b/Application/Cqrs/Discipline/Queries/GetDisciplineList/GetDisciplineListQuery.cs
@@ -0,0 +1,9 @@
+using MediatR;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Discipline.Queries.GetDisciplineList;
+
+public class GetDisciplineListQuery : IRequest
+{
+ public int? Page { get; set; }
+ public int? PageSize { get; set; }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Discipline/Queries/GetDisciplineList/GetDisciplineListQueryHandler.cs b/Application/Cqrs/Discipline/Queries/GetDisciplineList/GetDisciplineListQueryHandler.cs
new file mode 100644
index 0000000..c76ead2
--- /dev/null
+++ b/Application/Cqrs/Discipline/Queries/GetDisciplineList/GetDisciplineListQueryHandler.cs
@@ -0,0 +1,30 @@
+using MediatR;
+using Microsoft.EntityFrameworkCore;
+using Mirea.Api.DataAccess.Application.Interfaces.DbContexts.Schedule;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Discipline.Queries.GetDisciplineList;
+
+public class GetDisciplineListQueryHandler(IDisciplineDbContext dbContext) : IRequestHandler
+{
+ public async Task Handle(GetDisciplineListQuery request, CancellationToken cancellationToken)
+ {
+ var dtos = dbContext.Disciplines.OrderBy(d => d.Id).Select(d => new DisciplineLookupDto()
+ {
+ Id = d.Id,
+ Name = d.Name,
+ });
+
+ if (request is { PageSize: not null, Page: not null })
+ dtos = dtos.Skip(request.Page.Value * request.PageSize.Value).Take(request.PageSize.Value);
+
+ var result = await dtos.ToListAsync(cancellationToken);
+
+ return new DisciplineListVm
+ {
+ Disciplines = result
+ };
+ }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Faculty/Queries/GetFacultyDetails/FacultyInfoVm.cs b/Application/Cqrs/Faculty/Queries/GetFacultyDetails/FacultyInfoVm.cs
new file mode 100644
index 0000000..f7fb805
--- /dev/null
+++ b/Application/Cqrs/Faculty/Queries/GetFacultyDetails/FacultyInfoVm.cs
@@ -0,0 +1,32 @@
+namespace Mirea.Api.DataAccess.Application.Cqrs.Faculty.Queries.GetFacultyDetails;
+
+///
+/// Represents faculties.
+///
+public class FacultyInfoVm
+{
+ ///
+ /// The unique identifier for the faculty.
+ ///
+ public int Id { get; set; }
+
+ ///
+ /// The name of the faculty.
+ ///
+ public required string Name { get; set; }
+
+ ///
+ /// ID indicating the faculty's affiliation to the campus.
+ ///
+ public int? CampusId { get; set; }
+
+ ///
+ /// Campus name indicating the faculty's affiliation to the campus.
+ ///
+ public string? CampusName { get; set; }
+
+ ///
+ /// Campus code indicating the faculty's affiliation to the campus.
+ ///
+ public string? CampusCode { get; set; }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Faculty/Queries/GetFacultyDetails/GetFacultyInfoQuery.cs b/Application/Cqrs/Faculty/Queries/GetFacultyDetails/GetFacultyInfoQuery.cs
new file mode 100644
index 0000000..2517b14
--- /dev/null
+++ b/Application/Cqrs/Faculty/Queries/GetFacultyDetails/GetFacultyInfoQuery.cs
@@ -0,0 +1,8 @@
+using MediatR;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Faculty.Queries.GetFacultyDetails;
+
+public class GetFacultyInfoQuery : IRequest
+{
+ public required int Id { get; set; }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Faculty/Queries/GetFacultyDetails/GetFacultyInfoQueryHandler.cs b/Application/Cqrs/Faculty/Queries/GetFacultyDetails/GetFacultyInfoQueryHandler.cs
new file mode 100644
index 0000000..a2f6486
--- /dev/null
+++ b/Application/Cqrs/Faculty/Queries/GetFacultyDetails/GetFacultyInfoQueryHandler.cs
@@ -0,0 +1,27 @@
+using MediatR;
+using Microsoft.EntityFrameworkCore;
+using Mirea.Api.DataAccess.Application.Common.Exceptions;
+using Mirea.Api.DataAccess.Application.Interfaces.DbContexts.Schedule;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Faculty.Queries.GetFacultyDetails;
+
+public class GetFacultyInfoQueryHandler(IFacultyDbContext dbContext) : IRequestHandler
+{
+ public async Task Handle(GetFacultyInfoQuery request, CancellationToken cancellationToken)
+ {
+ var faculty = await dbContext.Faculties
+ .Include(f => f.Campus)
+ .FirstOrDefaultAsync(f => f.Id == request.Id, cancellationToken) ?? throw new NotFoundException(typeof(Domain.Schedule.Faculty), request.Id);
+
+ return new FacultyInfoVm()
+ {
+ Id = faculty.Id,
+ Name = faculty.Name,
+ CampusId = faculty.CampusId,
+ CampusName = faculty.Campus?.FullName,
+ CampusCode = faculty.Campus?.CodeName
+ };
+ }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Faculty/Queries/GetFacultyList/FacultyListVm.cs b/Application/Cqrs/Faculty/Queries/GetFacultyList/FacultyListVm.cs
new file mode 100644
index 0000000..8ad7d4b
--- /dev/null
+++ b/Application/Cqrs/Faculty/Queries/GetFacultyList/FacultyListVm.cs
@@ -0,0 +1,14 @@
+using System.Collections.Generic;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Faculty.Queries.GetFacultyList;
+
+///
+/// Represents a view model containing multiple faculties.
+///
+public class FacultyListVm
+{
+ ///
+ /// The list of faculties.
+ ///
+ public IList Faculties { get; set; } = new List();
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Faculty/Queries/GetFacultyList/FacultyLookupDto.cs b/Application/Cqrs/Faculty/Queries/GetFacultyList/FacultyLookupDto.cs
new file mode 100644
index 0000000..7a8c615
--- /dev/null
+++ b/Application/Cqrs/Faculty/Queries/GetFacultyList/FacultyLookupDto.cs
@@ -0,0 +1,22 @@
+namespace Mirea.Api.DataAccess.Application.Cqrs.Faculty.Queries.GetFacultyList;
+
+///
+/// Represents faculties.
+///
+public class FacultyLookupDto
+{
+ ///
+ /// The unique identifier for the faculty.
+ ///
+ public int Id { get; set; }
+
+ ///
+ /// The name of the faculty.
+ ///
+ public required string Name { get; set; }
+
+ ///
+ /// ID indicating the faculty's affiliation to the campus.
+ ///
+ public int? CampusId { get; set; }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Faculty/Queries/GetFacultyList/GetFacultyListQuery.cs b/Application/Cqrs/Faculty/Queries/GetFacultyList/GetFacultyListQuery.cs
new file mode 100644
index 0000000..9abe675
--- /dev/null
+++ b/Application/Cqrs/Faculty/Queries/GetFacultyList/GetFacultyListQuery.cs
@@ -0,0 +1,9 @@
+using MediatR;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Faculty.Queries.GetFacultyList;
+
+public class GetFacultyListQuery : IRequest
+{
+ public int? Page { get; set; }
+ public int? PageSize { get; set; }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Faculty/Queries/GetFacultyList/GetFacultyListQueryHandler.cs b/Application/Cqrs/Faculty/Queries/GetFacultyList/GetFacultyListQueryHandler.cs
new file mode 100644
index 0000000..1249fe7
--- /dev/null
+++ b/Application/Cqrs/Faculty/Queries/GetFacultyList/GetFacultyListQueryHandler.cs
@@ -0,0 +1,31 @@
+using MediatR;
+using Microsoft.EntityFrameworkCore;
+using Mirea.Api.DataAccess.Application.Interfaces.DbContexts.Schedule;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Faculty.Queries.GetFacultyList;
+
+public class GetFacultyListQueryHandler(IFacultyDbContext dbContext) : IRequestHandler
+{
+ public async Task Handle(GetFacultyListQuery request, CancellationToken cancellationToken)
+ {
+ var dtos = dbContext.Faculties.OrderBy(f => f.Id).Select(f => new FacultyLookupDto()
+ {
+ Id = f.Id,
+ Name = f.Name,
+ CampusId = f.CampusId
+ });
+
+ if (request is { PageSize: not null, Page: not null })
+ dtos = dtos.Skip(request.Page.Value * request.PageSize.Value).Take(request.PageSize.Value);
+
+ var result = await dtos.ToListAsync(cancellationToken);
+
+ return new FacultyListVm
+ {
+ Faculties = result
+ };
+ }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Group/Queries/GetGroupDetails/GetGroupInfoQuery.cs b/Application/Cqrs/Group/Queries/GetGroupDetails/GetGroupInfoQuery.cs
new file mode 100644
index 0000000..de0b87f
--- /dev/null
+++ b/Application/Cqrs/Group/Queries/GetGroupDetails/GetGroupInfoQuery.cs
@@ -0,0 +1,8 @@
+using MediatR;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Group.Queries.GetGroupDetails;
+
+public class GetGroupInfoQuery : IRequest
+{
+ public required int Id { get; set; }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Group/Queries/GetGroupDetails/GetGroupInfoQueryHandler.cs b/Application/Cqrs/Group/Queries/GetGroupDetails/GetGroupInfoQueryHandler.cs
new file mode 100644
index 0000000..4d1a092
--- /dev/null
+++ b/Application/Cqrs/Group/Queries/GetGroupDetails/GetGroupInfoQueryHandler.cs
@@ -0,0 +1,28 @@
+using MediatR;
+using Microsoft.EntityFrameworkCore;
+using Mirea.Api.DataAccess.Application.Common.Exceptions;
+using Mirea.Api.DataAccess.Application.Interfaces.DbContexts.Schedule;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Group
+ .Queries.GetGroupDetails;
+
+public class GetGroupInfoQueryHandler(IGroupDbContext dbContext) : IRequestHandler
+{
+ public async Task Handle(GetGroupInfoQuery request, CancellationToken cancellationToken)
+ {
+ var discipline = await dbContext.Groups
+ .Include(g => g.Faculty)
+ .FirstOrDefaultAsync(g => g.Id == request.Id, cancellationToken)
+ ?? throw new NotFoundException(typeof(Domain.Schedule.Group), request.Id);
+
+ return new GroupInfoVm()
+ {
+ Id = discipline.Id,
+ Name = discipline.Name,
+ Faculty = discipline.Faculty?.Name,
+ FacultyId = discipline.FacultyId
+ };
+ }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Group/Queries/GetGroupDetails/GroupInfoVm.cs b/Application/Cqrs/Group/Queries/GetGroupDetails/GroupInfoVm.cs
new file mode 100644
index 0000000..8a4999c
--- /dev/null
+++ b/Application/Cqrs/Group/Queries/GetGroupDetails/GroupInfoVm.cs
@@ -0,0 +1,27 @@
+namespace Mirea.Api.DataAccess.Application.Cqrs.Group.Queries.GetGroupDetails;
+
+///
+/// Represents groups.
+///
+public class GroupInfoVm
+{
+ ///
+ /// The unique identifier for the group.
+ ///
+ public int Id { get; set; }
+
+ ///
+ /// The name of the group.
+ ///
+ public required string Name { get; set; }
+
+ ///
+ /// The faculty name for the group.
+ ///
+ public string? Faculty { get; set; }
+
+ ///
+ /// The faculty identifier for the group.
+ ///
+ public int? FacultyId { get; set; }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Group/Queries/GetGroupList/GetGroupListQuery.cs b/Application/Cqrs/Group/Queries/GetGroupList/GetGroupListQuery.cs
new file mode 100644
index 0000000..7bcc6c9
--- /dev/null
+++ b/Application/Cqrs/Group/Queries/GetGroupList/GetGroupListQuery.cs
@@ -0,0 +1,9 @@
+using MediatR;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Group.Queries.GetGroupList;
+
+public class GetGroupListQuery : IRequest
+{
+ public int? Page { get; set; }
+ public int? PageSize { get; set; }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Group/Queries/GetGroupList/GetGroupListQueryHandler.cs b/Application/Cqrs/Group/Queries/GetGroupList/GetGroupListQueryHandler.cs
new file mode 100644
index 0000000..b0d63b1
--- /dev/null
+++ b/Application/Cqrs/Group/Queries/GetGroupList/GetGroupListQueryHandler.cs
@@ -0,0 +1,31 @@
+using MediatR;
+using Microsoft.EntityFrameworkCore;
+using Mirea.Api.DataAccess.Application.Interfaces.DbContexts.Schedule;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Group.Queries.GetGroupList;
+
+public class GetGroupListQueryHandler(IGroupDbContext dbContext) : IRequestHandler
+{
+ public async Task Handle(GetGroupListQuery request, CancellationToken cancellationToken)
+ {
+ var dtos = dbContext.Groups.OrderBy(g => g.Id).Select(g => new GroupLookupDto()
+ {
+ Id = g.Id,
+ Name = g.Name,
+ FacultyId = g.FacultyId
+ });
+
+ if (request is { PageSize: not null, Page: not null })
+ dtos = dtos.Skip(request.Page.Value * request.PageSize.Value).Take(request.PageSize.Value);
+
+ var result = await dtos.ToListAsync(cancellationToken);
+
+ return new GroupListVm
+ {
+ Groups = result
+ };
+ }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Group/Queries/GetGroupList/GroupListVm.cs b/Application/Cqrs/Group/Queries/GetGroupList/GroupListVm.cs
new file mode 100644
index 0000000..f4a777c
--- /dev/null
+++ b/Application/Cqrs/Group/Queries/GetGroupList/GroupListVm.cs
@@ -0,0 +1,14 @@
+using System.Collections.Generic;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Group.Queries.GetGroupList;
+
+///
+/// Represents a view model containing multiple groups name.
+///
+public class GroupListVm
+{
+ ///
+ /// The list of groups.
+ ///
+ public IList Groups { get; set; } = new List();
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Group/Queries/GetGroupList/GroupLookupDto.cs b/Application/Cqrs/Group/Queries/GetGroupList/GroupLookupDto.cs
new file mode 100644
index 0000000..306f8d2
--- /dev/null
+++ b/Application/Cqrs/Group/Queries/GetGroupList/GroupLookupDto.cs
@@ -0,0 +1,22 @@
+namespace Mirea.Api.DataAccess.Application.Cqrs.Group.Queries.GetGroupList;
+
+///
+/// Represents groups.
+///
+public class GroupLookupDto
+{
+ ///
+ /// The unique identifier for the group.
+ ///
+ public int Id { get; set; }
+
+ ///
+ /// The name of the group.
+ ///
+ public required string Name { get; set; }
+
+ ///
+ /// The faculty identifier for the group.
+ ///
+ public int? FacultyId { get; set; }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/LectureHall/Queries/GetLectureHallDetails/GetLectureHallInfoQuery.cs b/Application/Cqrs/LectureHall/Queries/GetLectureHallDetails/GetLectureHallInfoQuery.cs
new file mode 100644
index 0000000..284f218
--- /dev/null
+++ b/Application/Cqrs/LectureHall/Queries/GetLectureHallDetails/GetLectureHallInfoQuery.cs
@@ -0,0 +1,8 @@
+using MediatR;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.LectureHall.Queries.GetLectureHallDetails;
+
+public class GetLectureHallInfoQuery : IRequest
+{
+ public required int Id { get; set; }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/LectureHall/Queries/GetLectureHallDetails/GetLectureHallInfoQueryHandler.cs b/Application/Cqrs/LectureHall/Queries/GetLectureHallDetails/GetLectureHallInfoQueryHandler.cs
new file mode 100644
index 0000000..17027a6
--- /dev/null
+++ b/Application/Cqrs/LectureHall/Queries/GetLectureHallDetails/GetLectureHallInfoQueryHandler.cs
@@ -0,0 +1,28 @@
+using MediatR;
+using Microsoft.EntityFrameworkCore;
+using Mirea.Api.DataAccess.Application.Common.Exceptions;
+using Mirea.Api.DataAccess.Application.Interfaces.DbContexts.Schedule;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.LectureHall.Queries.GetLectureHallDetails;
+
+public class GetLectureHallInfoQueryHandler(ILectureHallDbContext dbContext) : IRequestHandler
+{
+ public async Task Handle(GetLectureHallInfoQuery request, CancellationToken cancellationToken)
+ {
+ var lectureHall = await dbContext.LectureHalls
+ .Include(l => l.Campus)
+ .FirstOrDefaultAsync(l => l.Id == request.Id, cancellationToken)
+ ?? throw new NotFoundException(typeof(Domain.Schedule.LectureHall), request.Id);
+
+ return new LectureHallInfoVm()
+ {
+ Id = lectureHall.Id,
+ Name = lectureHall.Name,
+ CampusId = lectureHall.CampusId,
+ CampusCode = lectureHall.Campus?.CodeName,
+ CampusName = lectureHall.Campus?.FullName
+ };
+ }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/LectureHall/Queries/GetLectureHallDetails/LectureHallInfoVm.cs b/Application/Cqrs/LectureHall/Queries/GetLectureHallDetails/LectureHallInfoVm.cs
new file mode 100644
index 0000000..9b9c42f
--- /dev/null
+++ b/Application/Cqrs/LectureHall/Queries/GetLectureHallDetails/LectureHallInfoVm.cs
@@ -0,0 +1,32 @@
+namespace Mirea.Api.DataAccess.Application.Cqrs.LectureHall.Queries.GetLectureHallDetails;
+
+///
+/// Represents disciplines.
+///
+public class LectureHallInfoVm
+{
+ ///
+ /// The unique identifier for the lecture hall.
+ ///
+ public int Id { get; set; }
+
+ ///
+ /// The name of the lecture hall.
+ ///
+ public required string Name { get; set; }
+
+ ///
+ /// ID indicating the lecture hall's affiliation to the campus.
+ ///
+ public int CampusId { get; set; }
+
+ ///
+ /// Campus name indicating the lecture hall's affiliation to the campus.
+ ///
+ public string? CampusName { get; set; }
+
+ ///
+ /// Campus code indicating the lecture hall's affiliation to the campus.
+ ///
+ public string? CampusCode { get; set; }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/LectureHall/Queries/GetLectureHallList/GetLectureHallListQuery.cs b/Application/Cqrs/LectureHall/Queries/GetLectureHallList/GetLectureHallListQuery.cs
new file mode 100644
index 0000000..cb8ea83
--- /dev/null
+++ b/Application/Cqrs/LectureHall/Queries/GetLectureHallList/GetLectureHallListQuery.cs
@@ -0,0 +1,9 @@
+using MediatR;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.LectureHall.Queries.GetLectureHallList;
+
+public class GetLectureHallListQuery : IRequest
+{
+ public int? Page { get; set; }
+ public int? PageSize { get; set; }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/LectureHall/Queries/GetLectureHallList/GetLectureHallListQueryHandler.cs b/Application/Cqrs/LectureHall/Queries/GetLectureHallList/GetLectureHallListQueryHandler.cs
new file mode 100644
index 0000000..ac7b041
--- /dev/null
+++ b/Application/Cqrs/LectureHall/Queries/GetLectureHallList/GetLectureHallListQueryHandler.cs
@@ -0,0 +1,31 @@
+using MediatR;
+using Microsoft.EntityFrameworkCore;
+using Mirea.Api.DataAccess.Application.Interfaces.DbContexts.Schedule;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.LectureHall.Queries.GetLectureHallList;
+
+public class GetLectureHallListQueryHandler(ILectureHallDbContext dbContext) : IRequestHandler
+{
+ public async Task Handle(GetLectureHallListQuery request, CancellationToken cancellationToken)
+ {
+ var dtos = dbContext.LectureHalls.OrderBy(l => l.Id).Select(l => new LectureHallLookupDto()
+ {
+ Id = l.Id,
+ Name = l.Name,
+ CampusId = l.CampusId
+ });
+
+ if (request is { PageSize: not null, Page: not null })
+ dtos = dtos.Skip(request.Page.Value * request.PageSize.Value).Take(request.PageSize.Value);
+
+ var result = await dtos.ToListAsync(cancellationToken);
+
+ return new LectureHallListVm
+ {
+ LectureHalls = result
+ };
+ }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/LectureHall/Queries/GetLectureHallList/LectureHallListVm.cs b/Application/Cqrs/LectureHall/Queries/GetLectureHallList/LectureHallListVm.cs
new file mode 100644
index 0000000..8338f99
--- /dev/null
+++ b/Application/Cqrs/LectureHall/Queries/GetLectureHallList/LectureHallListVm.cs
@@ -0,0 +1,14 @@
+using System.Collections.Generic;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.LectureHall.Queries.GetLectureHallList;
+
+///
+/// Represents a view model containing multiple disciplines name.
+///
+public class LectureHallListVm
+{
+ ///
+ /// The list of lecture hall.
+ ///
+ public IList LectureHalls { get; set; } = new List();
+}
\ No newline at end of file
diff --git a/Application/Cqrs/LectureHall/Queries/GetLectureHallList/LectureHallLookupDto.cs b/Application/Cqrs/LectureHall/Queries/GetLectureHallList/LectureHallLookupDto.cs
new file mode 100644
index 0000000..f00083c
--- /dev/null
+++ b/Application/Cqrs/LectureHall/Queries/GetLectureHallList/LectureHallLookupDto.cs
@@ -0,0 +1,22 @@
+namespace Mirea.Api.DataAccess.Application.Cqrs.LectureHall.Queries.GetLectureHallList;
+
+///
+/// Represents lecture halls.
+///
+public class LectureHallLookupDto
+{
+ ///
+ /// The unique identifier for the lecture hall.
+ ///
+ public int Id { get; set; }
+
+ ///
+ /// The name of the lecture hall.
+ ///
+ public required string Name { get; set; }
+
+ ///
+ /// ID indicating the lecture hall's affiliation to the campus.
+ ///
+ public int CampusId { get; set; }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Professor/Queries/GetProfessorDetails/GetProfessorInfoQuery.cs b/Application/Cqrs/Professor/Queries/GetProfessorDetails/GetProfessorInfoQuery.cs
new file mode 100644
index 0000000..93f1aa8
--- /dev/null
+++ b/Application/Cqrs/Professor/Queries/GetProfessorDetails/GetProfessorInfoQuery.cs
@@ -0,0 +1,8 @@
+using MediatR;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Professor.Queries.GetProfessorDetails;
+
+public class GetProfessorInfoQuery : IRequest
+{
+ public required int Id { get; set; }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Professor/Queries/GetProfessorDetails/GetProfessorInfoQueryHandler.cs b/Application/Cqrs/Professor/Queries/GetProfessorDetails/GetProfessorInfoQueryHandler.cs
new file mode 100644
index 0000000..868201d
--- /dev/null
+++ b/Application/Cqrs/Professor/Queries/GetProfessorDetails/GetProfessorInfoQueryHandler.cs
@@ -0,0 +1,22 @@
+using MediatR;
+using Microsoft.EntityFrameworkCore;
+using Mirea.Api.DataAccess.Application.Common.Exceptions;
+using Mirea.Api.DataAccess.Application.Interfaces.DbContexts.Schedule;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Professor.Queries.GetProfessorDetails;
+
+public class GetProfessorInfoQueryHandler(IProfessorDbContext dbContext) : IRequestHandler
+{
+ public async Task Handle(GetProfessorInfoQuery request, CancellationToken cancellationToken)
+ {
+ var discipline = await dbContext.Professors.FirstOrDefaultAsync(p => p.Id == request.Id, cancellationToken) ?? throw new NotFoundException(typeof(Domain.Schedule.Professor), request.Id);
+
+ return new ProfessorInfoVm()
+ {
+ Id = discipline.Id,
+ Name = discipline.Name,
+ };
+ }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Professor/Queries/GetProfessorDetails/ProfessorInfoVm.cs b/Application/Cqrs/Professor/Queries/GetProfessorDetails/ProfessorInfoVm.cs
new file mode 100644
index 0000000..691ef9b
--- /dev/null
+++ b/Application/Cqrs/Professor/Queries/GetProfessorDetails/ProfessorInfoVm.cs
@@ -0,0 +1,22 @@
+namespace Mirea.Api.DataAccess.Application.Cqrs.Professor.Queries.GetProfessorDetails;
+
+///
+/// Represents professors.
+///
+public class ProfessorInfoVm
+{
+ ///
+ /// The unique identifier for the professor.
+ ///
+ public int Id { get; set; }
+
+ ///
+ /// The name of the professor.
+ ///
+ public required string Name { get; set; }
+
+ ///
+ /// The alt name of the professor. Usually is full name.
+ ///
+ public string? AltName { get; set; }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Professor/Queries/GetProfessorList/GetProfessorListQuery.cs b/Application/Cqrs/Professor/Queries/GetProfessorList/GetProfessorListQuery.cs
new file mode 100644
index 0000000..1a2e14b
--- /dev/null
+++ b/Application/Cqrs/Professor/Queries/GetProfessorList/GetProfessorListQuery.cs
@@ -0,0 +1,9 @@
+using MediatR;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Professor.Queries.GetProfessorList;
+
+public class GetProfessorListQuery : IRequest
+{
+ public int? Page { get; set; }
+ public int? PageSize { get; set; }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Professor/Queries/GetProfessorList/GetProfessorListQueryHandler.cs b/Application/Cqrs/Professor/Queries/GetProfessorList/GetProfessorListQueryHandler.cs
new file mode 100644
index 0000000..adcff57
--- /dev/null
+++ b/Application/Cqrs/Professor/Queries/GetProfessorList/GetProfessorListQueryHandler.cs
@@ -0,0 +1,31 @@
+using MediatR;
+using Microsoft.EntityFrameworkCore;
+using Mirea.Api.DataAccess.Application.Interfaces.DbContexts.Schedule;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Professor.Queries.GetProfessorList;
+
+public class GetProfessorListQueryHandler(IProfessorDbContext dbContext) : IRequestHandler
+{
+ public async Task Handle(GetProfessorListQuery request, CancellationToken cancellationToken)
+ {
+ var dtos = dbContext.Professors.OrderBy(p => p.Id).Select(p => new ProfessorLookupDto()
+ {
+ Id = p.Id,
+ Name = p.Name,
+ AltName = p.AltName
+ });
+
+ if (request is { PageSize: not null, Page: not null })
+ dtos = dtos.Skip(request.Page.Value * request.PageSize.Value).Take(request.PageSize.Value);
+
+ var result = await dtos.ToListAsync(cancellationToken);
+
+ return new ProfessorListVm
+ {
+ Professors = result
+ };
+ }
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Professor/Queries/GetProfessorList/ProfessorListVm.cs b/Application/Cqrs/Professor/Queries/GetProfessorList/ProfessorListVm.cs
new file mode 100644
index 0000000..f3bf0f2
--- /dev/null
+++ b/Application/Cqrs/Professor/Queries/GetProfessorList/ProfessorListVm.cs
@@ -0,0 +1,14 @@
+using System.Collections.Generic;
+
+namespace Mirea.Api.DataAccess.Application.Cqrs.Professor.Queries.GetProfessorList;
+
+///
+/// Represents a view model containing multiple professors name.
+///
+public class ProfessorListVm
+{
+ ///
+ /// The list of professors.
+ ///
+ public IList Professors { get; set; } = new List();
+}
\ No newline at end of file
diff --git a/Application/Cqrs/Professor/Queries/GetProfessorList/ProfessorLookupDto.cs b/Application/Cqrs/Professor/Queries/GetProfessorList/ProfessorLookupDto.cs
new file mode 100644
index 0000000..4e32f26
--- /dev/null
+++ b/Application/Cqrs/Professor/Queries/GetProfessorList/ProfessorLookupDto.cs
@@ -0,0 +1,22 @@
+namespace Mirea.Api.DataAccess.Application.Cqrs.Professor.Queries.GetProfessorList;
+
+///
+/// Represents professor.
+///
+public class ProfessorLookupDto
+{
+ ///
+ /// The unique identifier for the professor.
+ ///
+ public int Id { get; set; }
+
+ ///
+ /// The name of the professor.
+ ///
+ public required string Name { get; set; }
+
+ ///
+ /// The alt name of the professor. Usually is full name.
+ ///
+ public string? AltName { get; set; }
+}
\ No newline at end of file