From 4f84851e0d90c6d8172b1b40432579d97fc8afc2 Mon Sep 17 00:00:00 2001 From: likdan Date: Mon, 27 Nov 2023 23:33:36 +0300 Subject: [PATCH] Improve schedule output --- internal/auth/entities/auth.go | 24 ++- internal/general/entities/entities.go | 1 + internal/schedule/controllers/controller.go | 160 +++++-------------- internal/schedule/entities/entities.go | 12 ++ internal/schedule/handlers/handler.go | 86 +--------- internal/schedule/repositories/repository.go | 51 ++++-- 6 files changed, 121 insertions(+), 213 deletions(-) diff --git a/internal/auth/entities/auth.go b/internal/auth/entities/auth.go index 6b08903..cc50410 100644 --- a/internal/auth/entities/auth.go +++ b/internal/auth/entities/auth.go @@ -5,14 +5,15 @@ import ( ) type User struct { - Id primitive.ObjectID `json:"id" bson:"_id"` - Password string `json:"-" bson:"password"` - Email string `json:"email" bson:"email"` - VerifiedEmail bool `json:"verifiedEmail" bson:"verifiedEmail"` - FirebaseToken string `json:"-" bson:"firebaseToken" encryption:""` - Login string `json:"login" bson:"login"` - PictureUrl string `json:"picture" bson:"picture" encryption:""` - StudyPlaceInfo *UserStudyPlaceInfo `json:"studyPlaceInfo" bson:"studyPlaceInfo" encryption:""` + Id primitive.ObjectID `json:"id" bson:"_id"` + Password string `json:"-" bson:"password"` + Email string `json:"email" bson:"email"` + VerifiedEmail bool `json:"verifiedEmail" bson:"verifiedEmail"` + FirebaseToken string `json:"-" bson:"firebaseToken" encryption:""` + Login string `json:"login" bson:"login"` + PictureUrl string `json:"picture" bson:"picture" encryption:""` + StudyPlaceInfo *UserStudyPlaceInfo `json:"studyPlaceInfo" bson:"studyPlaceInfo" encryption:""` + SchedulePreferences *UserSchedulePreferences `json:"schedulePreferences" bson:"schedulePreferences"` } type UserStudyPlaceInfo struct { @@ -24,3 +25,10 @@ type UserStudyPlaceInfo struct { Permissions []string `json:"permissions" bson:"permissions"` Accepted bool `json:"accepted" bson:"accepted"` } + +type UserSchedulePreferences struct { + StudyPlaceID primitive.ObjectID `json:"studyPlaceID" bson:"studyPlaceID"` + Type string `json:"type" bson:"type"` + TypeID primitive.ObjectID `json:"typeID" bson:"typeID"` + ViewMode string `json:"viewMode" bson:"viewMode"` +} diff --git a/internal/general/entities/entities.go b/internal/general/entities/entities.go index 6b42927..5714f4e 100755 --- a/internal/general/entities/entities.go +++ b/internal/general/entities/entities.go @@ -21,6 +21,7 @@ type StudyPlace struct { Restricted bool `json:"restricted" bson:"restricted"` AdminID primitive.ObjectID `json:"adminID" bson:"adminID"` AbsenceMark string `json:"absenceMark" bson:"absenceMark"` + IsSchedulePrivate bool `json:"IsSchedulePrivate" bson:"IsSchedulePrivate"` } type MarkType struct { diff --git a/internal/schedule/controllers/controller.go b/internal/schedule/controllers/controller.go index a655b1b..e07924a 100755 --- a/internal/schedule/controllers/controller.go +++ b/internal/schedule/controllers/controller.go @@ -18,13 +18,11 @@ import ( ) var NotValidParams = errors.New("not valid params") +var NoPermission = errors.New("no permission") type Controller interface { - GetSchedule(ctx context.Context, user auth.User, studyPlaceID, role, roleName string, startDate, endDate time.Time, isGeneral bool) (entities.Schedule, error) - GetUserSchedule(ctx context.Context, user auth.User, startDate, endDate time.Time, isGeneral bool) (entities.Schedule, error) - - GetGeneralSchedule(ctx context.Context, user auth.User, studyPlaceID string, role string, roleName string, startDate, endDate time.Time) (entities.Schedule, error) - GetGeneralUserSchedule(ctx context.Context, user auth.User, startDate, endDate time.Time) (entities.Schedule, error) + GetSchedule(ctx context.Context, user auth.User, studyPlaceID, role, roleName string, startDate, endDate time.Time) (entities.Schedule, error) + GetGeneralSchedule(ctx context.Context, user auth.User, studyPlaceID string, role string, roleName string) (entities.GeneralSchedule, error) GetScheduleTypes(ctx context.Context, user auth.User, idHex string) entities.Types @@ -73,123 +71,61 @@ func (s *controller) scheduleDated(start, end time.Time) (time.Time, time.Time) return start, end } -func (s *controller) GetSchedule(ctx context.Context, user auth.User, studyPlaceIDHex, type_, typeIDStr string, startDate, endDate time.Time, isGeneral bool) (entities.Schedule, error) { - typeID, err := primitive.ObjectIDFromHex(typeIDStr) - if err != nil { - return entities.Schedule{}, err - } - - if type_ == "" || typeID.IsZero() { - return entities.Schedule{}, NotValidParams - } - - var studyPlaceID primitive.ObjectID - if user.StudyPlaceInfo != nil { - studyPlaceID = user.StudyPlaceInfo.ID - } - - if id, err := primitive.ObjectIDFromHex(studyPlaceIDHex); err == nil { - studyPlaceID = id - } - - startDate, endDate = s.scheduleDated(startDate, endDate) - - if type_ == "student" { - type_ = "group" - } - - typeName, err := s.repository.GetTypeName(ctx, type_, typeID) - if err != nil { - return entities.Schedule{}, err - } +func (s *controller) proceedParams(ctx context.Context, user auth.User, studyPlaceIDHex string, type_ string, typeIDHex string) (primitive.ObjectID, string, primitive.ObjectID, error) { + studyPlaceID, err := primitive.ObjectIDFromHex(studyPlaceIDHex) + if err == nil { + err, studyPlace := s.repository.GetStudyPlaceByID(ctx, studyPlaceID) + if err != nil { + return primitive.ObjectID{}, "", primitive.ObjectID{}, NotValidParams + } - lessons, err := s.repository.GetSchedule(ctx, studyPlaceID, type_, typeID, startDate, endDate, isGeneral, false) - if err != nil { - return entities.Schedule{}, err + if studyPlace.IsSchedulePrivate && (user.SchedulePreferences == nil || user.StudyPlaceInfo.ID != studyPlace.Id) { + return primitive.ObjectID{}, "", primitive.ObjectID{}, NoPermission + } } - return entities.Schedule{ - Info: entities.Info{ - StudyPlaceInfo: entities.StudyPlaceInfo{}, //todo - Type: type_, - TypeName: typeName, - StartDate: startDate, - EndDate: endDate, - Date: time.Now(), - }, - Lessons: lessons, - }, nil -} - -func (s *controller) GetUserSchedule(ctx context.Context, user auth.User, startDate, endDate time.Time, isGeneral bool) (entities.Schedule, error) { - if user.StudyPlaceInfo.Role == "" || user.StudyPlaceInfo.RoleName == "" { - return entities.Schedule{}, NotValidParams - } + if err != nil || studyPlaceID.IsZero() { + if user.SchedulePreferences == nil { + return primitive.ObjectID{}, "", primitive.ObjectID{}, NotValidParams + } - typeID, err := primitive.ObjectIDFromHex(user.StudyPlaceInfo.RoleName) - if err != nil { - return entities.Schedule{}, err + studyPlaceID = user.SchedulePreferences.StudyPlaceID } - startDate, endDate = s.scheduleDated(startDate, endDate) + typeID, err := primitive.ObjectIDFromHex(typeIDHex) + if err != nil || typeID.IsZero() { + if user.SchedulePreferences == nil { + return primitive.ObjectID{}, "", primitive.ObjectID{}, NotValidParams + } - type_ := user.StudyPlaceInfo.RoleName - if type_ == "student" { - type_ = "group" + typeID = user.SchedulePreferences.TypeID } - typeName, err := s.repository.GetTypeName(ctx, type_, typeID) - if err != nil { - return entities.Schedule{}, err - } + if type_ == "" { + if user.SchedulePreferences == nil { + return primitive.ObjectID{}, "", primitive.ObjectID{}, NotValidParams + } - lessons, err := s.repository.GetSchedule(ctx, user.StudyPlaceInfo.ID, user.StudyPlaceInfo.Role, typeID, startDate, endDate, isGeneral, false) - if err != nil { - return entities.Schedule{}, err + type_ = user.SchedulePreferences.Type } - return entities.Schedule{ - Info: entities.Info{ - StudyPlaceInfo: entities.StudyPlaceInfo{}, //todo - Type: type_, - TypeName: typeName, - StartDate: startDate, - EndDate: endDate, - Date: time.Now(), - }, - Lessons: lessons, - }, nil + return studyPlaceID, type_, typeID, nil } -func (s *controller) GetGeneralSchedule(ctx context.Context, user auth.User, studyPlaceIDHex string, type_ string, typeIDStr string, startDate, endDate time.Time) (entities.Schedule, error) { - typeID, err := primitive.ObjectIDFromHex(typeIDStr) +func (s *controller) GetSchedule(ctx context.Context, user auth.User, studyPlaceIDHex, type_, typeIDHex string, startDate, endDate time.Time) (entities.Schedule, error) { + studyPlaceID, type_, typeID, err := s.proceedParams(ctx, user, studyPlaceIDHex, type_, typeIDHex) if err != nil { return entities.Schedule{}, err } - if type_ == "" || typeID.IsZero() { - return entities.Schedule{}, NotValidParams - } - - studyPlaceID := user.StudyPlaceInfo.ID - restricted := true - if id, err := primitive.ObjectIDFromHex(studyPlaceIDHex); err == nil && id != user.StudyPlaceInfo.ID { - studyPlaceID = id - restricted = false - } - startDate, endDate = s.scheduleDated(startDate, endDate) - if type_ == "student" { - type_ = "group" - } - typeName, err := s.repository.GetTypeName(ctx, type_, typeID) if err != nil { return entities.Schedule{}, err } - lessons, err := s.repository.GetSchedule(ctx, studyPlaceID, type_, typeID, startDate, endDate, true, !restricted) + lessons, err := s.repository.GetSchedule(ctx, studyPlaceID, type_, typeID, startDate, endDate) if err != nil { return entities.Schedule{}, err } @@ -207,39 +143,27 @@ func (s *controller) GetGeneralSchedule(ctx context.Context, user auth.User, stu }, nil } -func (s *controller) GetGeneralUserSchedule(ctx context.Context, user auth.User, startDate, endDate time.Time) (entities.Schedule, error) { - startDate, endDate = s.scheduleDated(startDate, endDate) - - typeID, err := primitive.ObjectIDFromHex(user.StudyPlaceInfo.RoleName) - if err != nil { - return entities.Schedule{}, err - } - - type_ := user.StudyPlaceInfo.RoleName - if type_ == "student" { - type_ = "group" - } +func (s *controller) GetGeneralSchedule(ctx context.Context, user auth.User, studyPlaceIDHex string, type_ string, typeIDHex string) (entities.GeneralSchedule, error) { + studyPlaceID, type_, typeID, err := s.proceedParams(ctx, user, studyPlaceIDHex, type_, typeIDHex) typeName, err := s.repository.GetTypeName(ctx, type_, typeID) if err != nil { - return entities.Schedule{}, err + return entities.GeneralSchedule{}, err } - lessons, err := s.repository.GetSchedule(ctx, user.StudyPlaceInfo.ID, user.StudyPlaceInfo.Role, typeID, startDate, endDate, true, false) + lessons, err := s.repository.GetGeneralSchedule(ctx, studyPlaceID, type_, typeID) if err != nil { - return entities.Schedule{}, err + return entities.GeneralSchedule{}, err } - return entities.Schedule{ - Info: entities.Info{ + return entities.GeneralSchedule{ + Info: entities.GeneralInfo{ StudyPlaceInfo: entities.StudyPlaceInfo{}, //todo Type: type_, TypeName: typeName, - StartDate: startDate, - EndDate: endDate, Date: time.Now(), }, - Lessons: lessons, + GeneralLessons: lessons, }, nil } @@ -400,7 +324,7 @@ func (s *controller) UpdateLesson(ctx context.Context, lessonIDHex string, updat Description: updateDTO.Description, } - err, studyPlace := s.repository.GetStudyPlaceByID(ctx, user.StudyPlaceInfo.ID, false) + err, studyPlace := s.repository.GetStudyPlaceByID(ctx, user.StudyPlaceInfo.ID) if err != nil { return entities.Lesson{}, err } diff --git a/internal/schedule/entities/entities.go b/internal/schedule/entities/entities.go index 8f99b0f..3536360 100755 --- a/internal/schedule/entities/entities.go +++ b/internal/schedule/entities/entities.go @@ -11,6 +11,11 @@ type Schedule struct { Lessons []Lesson `json:"lessons" bson:"lessons"` } +type GeneralSchedule struct { + Info GeneralInfo `json:"info" bson:"info"` + GeneralLessons []GeneralLesson `json:"lessons" bson:"lessons"` +} + type DeleteLessonID struct { ID primitive.ObjectID `apps:"trackable,collection=Lessons"` } @@ -72,6 +77,13 @@ type Info struct { Date time.Time `json:"date" bson:"date"` } +type GeneralInfo struct { + StudyPlaceInfo StudyPlaceInfo `json:"studyPlaceInfo" bson:"studyPlaceInfo"` + Type string `json:"type" bson:"type"` + TypeName string `json:"typeName" bson:"typeName"` + Date time.Time `json:"date" bson:"date"` +} + type StudyPlaceInfo struct { Id primitive.ObjectID `json:"id" bson:"_id"` Title string `json:"title" bson:"title"` diff --git a/internal/schedule/handlers/handler.go b/internal/schedule/handlers/handler.go index ab6d142..1ea94d1 100755 --- a/internal/schedule/handlers/handler.go +++ b/internal/schedule/handlers/handler.go @@ -12,10 +12,7 @@ import ( type Handler interface { GetSchedule(ctx *gin.Context) - GetUserSchedule(ctx *gin.Context) - GetGeneralSchedule(ctx *gin.Context) - GetGeneralUserSchedule(ctx *gin.Context) GetGeneralLessonsList(ctx *gin.Context) @@ -46,11 +43,8 @@ type handler struct { func NewScheduleHandler(middleware auth.Middleware, controller controllers.Controller, group *gin.RouterGroup) Handler { h := &handler{Middleware: middleware, controller: controller, Group: group} - //group.GET(":type/:name", h.TryAuth(), h.GetSchedule) - group.GET("", h.TryAuth(), h.GetUserSchedule) - - group.GET("general/:type/:name", h.MemberAuth(), h.GetGeneralSchedule) - group.GET("general", h.MemberAuth(), h.GetGeneralUserSchedule) + group.GET("", h.TryAuth(), h.GetSchedule) + group.GET("general", h.TryAuth(), h.GetGeneralSchedule) group.GET("types", h.TryAuth(), h.GetScheduleTypes) //todo change endpoint to types @@ -79,31 +73,8 @@ func NewScheduleHandler(middleware auth.Middleware, controller controllers.Contr // GetSchedule godoc // @Param type path string true "Role" // @Param name path string true "RoleName" -// @Router /{type}/{name} [get] -func (s *handler) GetSchedule(ctx *gin.Context) { - user := s.GetUser(ctx) - - studyPlaceID := ctx.Query("studyPlaceID") - startDateStr := ctx.Query("startDate") - startDate, _ := time.Parse(time.RFC3339, startDateStr) - endDateStr := ctx.Query("endDate") - endDate, _ := time.Parse(time.RFC3339, endDateStr) - - type_ := ctx.Param("type") - typeID := ctx.Param("name") - - schedule, err := s.controller.GetSchedule(ctx, user, studyPlaceID, type_, typeID, startDate, endDate, false) - if err != nil { - _ = ctx.Error(err) - return - } - - ctx.JSON(http.StatusOK, schedule) -} - -// GetUserSchedule godoc // @Router / [get] -func (s *handler) GetUserSchedule(ctx *gin.Context) { +func (s *handler) GetSchedule(ctx *gin.Context) { user := s.GetUser(ctx) startDateStr := ctx.Query("startDate") @@ -112,26 +83,10 @@ func (s *handler) GetUserSchedule(ctx *gin.Context) { endDate, _ := time.Parse(time.RFC3339, endDateStr) studyPlaceID := ctx.Query("studyPlaceID") - if studyPlaceID == "" { - studyPlaceID = user.StudyPlaceInfo.ID.Hex() - } - type_ := ctx.Query("type") typeID := ctx.Query("typeID") - isGeneral := ctx.Query("general") == "true" - - if type_ != "" && typeID != "" { - schedule, err := s.controller.GetSchedule(ctx, user, studyPlaceID, type_, typeID, startDate, endDate, isGeneral) - if err != nil { - _ = ctx.Error(err) - return - } - ctx.JSON(http.StatusOK, schedule) - return - } - - schedule, err := s.controller.GetUserSchedule(ctx, user, startDate, endDate, isGeneral) + schedule, err := s.controller.GetSchedule(ctx, user, studyPlaceID, type_, typeID, startDate, endDate) if err != nil { _ = ctx.Error(err) return @@ -143,21 +98,15 @@ func (s *handler) GetUserSchedule(ctx *gin.Context) { // GetGeneralSchedule godoc // @Param type path string true "Type" // @Param name path string true "RoleName" -// @Router /general/{type}/{name} [get] +// @Router /general [get] func (s *handler) GetGeneralSchedule(ctx *gin.Context) { user := s.GetUser(ctx) studyPlaceID := ctx.Query("studyPlaceID") + type_ := ctx.Query("type") + typeID := ctx.Query("typeID") - role := ctx.Param("type") - roleName := ctx.Param("name") - - startDateStr := ctx.Query("startDate") - startDate, _ := time.Parse(time.RFC3339, startDateStr) - endDateStr := ctx.Query("endDate") - endDate, _ := time.Parse(time.RFC3339, endDateStr) - - schedule, err := s.controller.GetGeneralSchedule(ctx, user, studyPlaceID, role, roleName, startDate, endDate) + schedule, err := s.controller.GetGeneralSchedule(ctx, user, studyPlaceID, type_, typeID) if err != nil { _ = ctx.Error(err) return @@ -197,25 +146,6 @@ func (s *handler) GetGeneralLessonsList(ctx *gin.Context) { ctx.JSON(http.StatusOK, lessons) } -// GetGeneralUserSchedule godoc -// @Router /general [get] -func (s *handler) GetGeneralUserSchedule(ctx *gin.Context) { - user := s.GetUser(ctx) - - startDateStr := ctx.Query("startDate") - startDate, _ := time.Parse(time.RFC3339, startDateStr) - endDateStr := ctx.Query("endDate") - endDate, _ := time.Parse(time.RFC3339, endDateStr) - - schedule, err := s.controller.GetGeneralUserSchedule(ctx, user, startDate, endDate) - if err != nil { - _ = ctx.Error(err) - return - } - - ctx.JSON(http.StatusOK, schedule) -} - // GetScheduleTypes godoc // @Router /getTypes [get] func (s *handler) GetScheduleTypes(ctx *gin.Context) { diff --git a/internal/schedule/repositories/repository.go b/internal/schedule/repositories/repository.go index 0dec526..4486db6 100755 --- a/internal/schedule/repositories/repository.go +++ b/internal/schedule/repositories/repository.go @@ -16,7 +16,8 @@ import ( type Repository interface { GetTypeID(ctx context.Context, studyPlaceID primitive.ObjectID, type_, typeName string) (primitive.ObjectID, error) - GetSchedule(ctx context.Context, studyPlaceID primitive.ObjectID, type_ string, typeID primitive.ObjectID, startDate, endDate time.Time, onlyGeneral bool, _ bool) ([]entities.Lesson, error) + GetSchedule(ctx context.Context, studyPlaceID primitive.ObjectID, type_ string, typeID primitive.ObjectID, startDate, endDate time.Time) ([]entities.Lesson, error) + GetGeneralSchedule(ctx context.Context, studyPlaceID primitive.ObjectID, type_ string, typeID primitive.ObjectID) ([]entities.GeneralLesson, error) GetScheduleType(ctx context.Context, studyPlaceID primitive.ObjectID, role string, property string) (entries []entities.TypeEntry, err error) GetScheduleTeacherType(ctx context.Context, studyPlaceID primitive.ObjectID) (entries []entities.TypeEntry, err error) @@ -38,7 +39,7 @@ type Repository interface { RemoveGeneralLessonsByType(ctx context.Context, studyPlaceID primitive.ObjectID, role string, roleName string) error - GetStudyPlaceByID(ctx context.Context, id primitive.ObjectID, restricted bool) (err error, studyPlace general.StudyPlace) + GetStudyPlaceByID(ctx context.Context, id primitive.ObjectID) (err error, studyPlace general.StudyPlace) GetGeneralLessons(ctx context.Context, studyPlaceID primitive.ObjectID, weekIndex, dayIndex int) ([]entities.GeneralLesson, error) GetAllGeneralLessons(ctx context.Context, studyPlaceID primitive.ObjectID) ([]entities.GeneralLesson, error) @@ -98,12 +99,12 @@ func (s *repository) GetTypeID(ctx context.Context, studyPlaceID primitive.Objec return value.ID, nil } -func (s *repository) GetStudyPlaceByID(ctx context.Context, id primitive.ObjectID, restricted bool) (err error, studyPlace general.StudyPlace) { - err = s.studyPlaces.FindOne(ctx, bson.M{"_id": id, "restricted": restricted}).Decode(&studyPlace) +func (s *repository) GetStudyPlaceByID(ctx context.Context, id primitive.ObjectID) (err error, studyPlace general.StudyPlace) { + err = s.studyPlaces.FindOne(ctx, bson.M{"_id": id}).Decode(&studyPlace) return } -func (s *repository) GetSchedule(ctx context.Context, studyPlaceID primitive.ObjectID, type_ string, typeID primitive.ObjectID, startDate, endDate time.Time, isGeneral bool, _ bool) ([]entities.Lesson, error) { +func (s *repository) GetSchedule(ctx context.Context, studyPlaceID primitive.ObjectID, type_ string, typeID primitive.ObjectID, startDate, endDate time.Time) ([]entities.Lesson, error) { cursor, err := s.schedule.Aggregate(ctx, bson.A{ bson.M{ "$match": bson.M{ @@ -119,7 +120,6 @@ func (s *repository) GetSchedule(ctx context.Context, studyPlaceID primitive.Obj "pipeline": bson.A{ bson.M{ "$match": bson.M{"$expr": bson.M{"$and": bson.A{ - bson.M{"$eq": bson.A{isGeneral, false}}, bson.M{"$eq": bson.A{"$studyPlaceID", studyPlaceID}}, bson.M{"$eq": bson.A{"$$date", bson.M{"$dateTrunc": bson.M{"date": "$startDate", "unit": "day"}}}}, bson.M{"$eq": bson.A{"$" + type_ + "ID", typeID}}, @@ -141,17 +141,17 @@ func (s *repository) GetSchedule(ctx context.Context, studyPlaceID primitive.Obj "$project": bson.M{ "items": bson.M{ "$function": bson.M{ - "body": `function (items, start, end, isGeneral) { + "body": `function (items, start, end) { const currentDate = new Date(start); while (currentDate <= end) { - if (isGeneral || !items.some(item => item.date.getTime() === currentDate.getTime())) { + if (!items.some(item => item.date.getTime() === currentDate.getTime())) { items.push({date: new Date(currentDate)}); } currentDate.setDate(currentDate.getDate() + 1); } return items; }`, - "args": bson.A{"$items", startDate, endDate, isGeneral}, + "args": bson.A{"$items", startDate, endDate}, "lang": "js", }, }, @@ -234,6 +234,39 @@ return items; return lessons, nil } +func (s *repository) GetGeneralSchedule(ctx context.Context, studyPlaceID primitive.ObjectID, type_ string, typeID primitive.ObjectID) ([]entities.GeneralLesson, error) { + cursor, err := s.generalLessons.Aggregate(ctx, bson.A{ + bson.M{ + "$match": bson.M{ + "studyPlaceID": studyPlaceID, + type_ + "ID": typeID, + }, + }, + bson.M{"$lookup": bson.M{"from": "StudyPlaceUsers", "localField": "teacherID", "foreignField": "_id", "as": "teacher"}}, + bson.M{"$lookup": bson.M{"from": "Groups", "localField": "groupID", "foreignField": "_id", "as": "group"}}, + bson.M{"$lookup": bson.M{"from": "Subjects", "localField": "subjectID", "foreignField": "_id", "as": "subject"}}, + bson.M{"$lookup": bson.M{"from": "Rooms", "localField": "roomID", "foreignField": "_id", "as": "room"}}, + bson.M{ + "$addFields": bson.M{ + "subject": bson.M{"$first": "$subject.subject"}, + "room": bson.M{"$first": "$room.room"}, + "teacher": bson.M{"$first": "$teacher.roleName"}, + "group": bson.M{"$first": "$group.group"}, + }, + }, + }) + if err != nil { + return nil, err + } + + var lessons []entities.GeneralLesson + if err = cursor.All(ctx, &lessons); err != nil { + return nil, err + } + + return lessons, nil +} + func (s *repository) GetScheduleType(ctx context.Context, studyPlaceID primitive.ObjectID, role string, property string) (entries []entities.TypeEntry, err error) { result, err := s.database.Collection(role).Find(ctx, bson.M{"studyPlaceID": studyPlaceID}, &options.FindOptions{ Projection: bson.M{"_id": 1, "title": "$" + property},