Yimaru-BackEnd/internal/repository/learning_tree.go
2026-03-05 07:58:48 -08:00

159 lines
4.6 KiB
Go

package repository
import (
"Yimaru-Backend/internal/domain"
"context"
"fmt"
"github.com/jackc/pgx/v5/pgtype"
)
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)
for _, row := range rows {
course, ok := coursesMap[row.CourseID]
if !ok {
course = &domain.TreeCourse{
ID: row.CourseID,
Title: row.CourseTitle,
SubCourses: []domain.TreeSubCourse{},
}
coursesMap[row.CourseID] = course
}
if row.SubCourseID.Valid {
subCourse := domain.TreeSubCourse{
ID: row.SubCourseID.Int64,
Title: row.SubCourseTitle.String,
Level: row.SubCourseLevel.String,
}
course.SubCourses = append(course.SubCourses, subCourse)
}
}
courses := make([]domain.TreeCourse, 0, len(coursesMap))
for _, course := range coursesMap {
courses = append(courses, *course)
}
return courses, nil
}
func (s *Store) GetCourseLearningPath(ctx context.Context, courseID int64) (domain.LearningPath, error) {
rows, err := s.queries.GetCourseLearningPath(ctx, courseID)
if err != nil {
return domain.LearningPath{}, err
}
if len(rows) == 0 {
return domain.LearningPath{}, fmt.Errorf("course not found")
}
first := rows[0]
path := domain.LearningPath{
CourseID: first.CourseID,
CourseTitle: first.CourseTitle,
Description: ptrString(first.CourseDescription),
Thumbnail: ptrString(first.CourseThumbnail),
IntroVideoURL: ptrString(first.CourseIntroVideoUrl),
CategoryID: first.CategoryID,
CategoryName: first.CategoryName,
SubCourses: []domain.LearningPathSubCourse{},
}
for _, row := range rows {
if !row.SubCourseID.Valid {
continue
}
scID := row.SubCourseID.Int64
// Fetch prerequisites, videos, practices for this sub-course
prerequisites, _ := s.getSubCoursePrerequisitesForPath(ctx, scID)
videos, _ := s.getSubCourseVideosForPath(ctx, scID)
practices, _ := s.getSubCoursePracticesForPath(ctx, scID)
sc := domain.LearningPathSubCourse{
ID: scID,
Title: row.SubCourseTitle.String,
Description: ptrString(row.SubCourseDescription),
Thumbnail: ptrString(row.SubCourseThumbnail),
DisplayOrder: row.SubCourseDisplayOrder.Int32,
Level: row.SubCourseLevel.String,
PrerequisiteCount: row.PrerequisiteCount,
VideoCount: row.VideoCount,
PracticeCount: row.PracticeCount,
Prerequisites: prerequisites,
Videos: videos,
Practices: practices,
}
path.SubCourses = append(path.SubCourses, sc)
}
return path, nil
}
func (s *Store) getSubCoursePrerequisitesForPath(ctx context.Context, subCourseID int64) ([]domain.LearningPathPrerequisite, error) {
rows, err := s.queries.GetSubCoursePrerequisitesForLearningPath(ctx, subCourseID)
if err != nil {
return nil, err
}
result := make([]domain.LearningPathPrerequisite, len(rows))
for i, row := range rows {
result[i] = domain.LearningPathPrerequisite{
SubCourseID: row.PrerequisiteSubCourseID,
Title: row.Title,
Level: row.Level,
}
}
return result, nil
}
func (s *Store) getSubCourseVideosForPath(ctx context.Context, subCourseID int64) ([]domain.LearningPathVideo, error) {
rows, err := s.queries.GetSubCourseVideosForLearningPath(ctx, subCourseID)
if err != nil {
return nil, err
}
result := make([]domain.LearningPathVideo, len(rows))
for i, row := range rows {
result[i] = domain.LearningPathVideo{
ID: row.ID,
Title: row.Title,
Description: ptrString(row.Description),
VideoURL: row.VideoUrl,
Duration: row.Duration,
Resolution: ptrString(row.Resolution),
DisplayOrder: row.DisplayOrder,
VimeoID: ptrString(row.VimeoID),
VimeoEmbedURL: ptrString(row.VimeoEmbedUrl),
VideoHostProvider: ptrString(row.VideoHostProvider),
}
}
return result, nil
}
func (s *Store) getSubCoursePracticesForPath(ctx context.Context, subCourseID int64) ([]domain.LearningPathPractice, error) {
ownerID := pgtype.Int8{Int64: subCourseID, Valid: true}
rows, err := s.queries.GetSubCoursePracticesForLearningPath(ctx, ownerID)
if err != nil {
return nil, err
}
result := make([]domain.LearningPathPractice, len(rows))
for i, row := range rows {
result[i] = domain.LearningPathPractice{
ID: row.ID,
Title: row.Title,
Description: ptrString(row.Description),
Persona: ptrString(row.Persona),
Status: row.Status,
QuestionCount: row.QuestionCount,
}
}
return result, nil
}