162 lines
4.7 KiB
Go
162 lines
4.7 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,
|
|
SubLevel: row.SubCourseSubLevel.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,
|
|
SubLevel: row.SubCourseSubLevel.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,
|
|
SubLevel: row.SubLevel,
|
|
}
|
|
}
|
|
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
|
|
}
|