package repository import ( "Yimaru-Backend/internal/domain" "context" ) func (s *Store) GetFullLearningTree(ctx context.Context) ([]domain.TreeCourse, error) { rows, err := s.queries.GetFullLearningTree(ctx) if err != nil { return nil, err } coursesMap := make(map[int64]*domain.TreeCourse) programsMap := make(map[int64]*domain.TreeProgram) levelsMap := make(map[int64]*domain.TreeLevel) for _, row := range rows { // COURSE course, ok := coursesMap[row.CourseID] if !ok { course = &domain.TreeCourse{ ID: row.CourseID, Title: row.CourseTitle, Programs: []domain.TreeProgram{}, } coursesMap[row.CourseID] = course } // PROGRAM program, ok := programsMap[row.ProgramID] if !ok { program = &domain.TreeProgram{ ID: row.ProgramID, Title: row.ProgramTitle, Levels: []domain.TreeLevel{}, } programsMap[row.ProgramID] = program course.Programs = append(course.Programs, *program) } // LEVEL level, ok := levelsMap[row.LevelID] if !ok { level = &domain.TreeLevel{ ID: row.LevelID, Title: row.LevelTitle, Modules: []domain.TreeModule{}, } levelsMap[row.LevelID] = level // Append level to its program for i := range course.Programs { if course.Programs[i].ID == row.ProgramID { course.Programs[i].Levels = append(course.Programs[i].Levels, *level) break } } } // MODULE (may be nil) if row.ModuleID.Valid { module := domain.TreeModule{ ID: row.ModuleID.Int64, Title: row.ModuleTitle.String, } // Append module to its level for i := range course.Programs { if course.Programs[i].ID == row.ProgramID { for j := range course.Programs[i].Levels { if course.Programs[i].Levels[j].ID == row.LevelID { course.Programs[i].Levels[j].Modules = append(course.Programs[i].Levels[j].Modules, module) break } } break } } } } // Flatten map to slice courses := make([]domain.TreeCourse, 0, len(coursesMap)) for _, course := range coursesMap { courses = append(courses, *course) } return courses, nil }