Yimaru-BackEnd/internal/repository/progression.go

227 lines
7.4 KiB
Go

package repository
import (
dbgen "Yimaru-Backend/gen/db"
"Yimaru-Backend/internal/domain"
"Yimaru-Backend/internal/ports"
"context"
"errors"
"time"
"github.com/jackc/pgx/v5"
)
func NewProgressionStore(s *Store) ports.ProgressionStore { return s }
func (s *Store) AddSubCoursePrerequisite(ctx context.Context, subCourseID, prerequisiteSubCourseID int64) error {
_, err := s.queries.AddSubCoursePrerequisite(ctx, dbgen.AddSubCoursePrerequisiteParams{
SubCourseID: subCourseID,
PrerequisiteSubCourseID: prerequisiteSubCourseID,
})
return err
}
func (s *Store) RemoveSubCoursePrerequisite(ctx context.Context, subCourseID, prerequisiteSubCourseID int64) error {
return s.queries.RemoveSubCoursePrerequisite(ctx, dbgen.RemoveSubCoursePrerequisiteParams{
SubCourseID: subCourseID,
PrerequisiteSubCourseID: prerequisiteSubCourseID,
})
}
func (s *Store) GetSubCoursePrerequisites(ctx context.Context, subCourseID int64) ([]domain.SubCoursePrerequisite, error) {
rows, err := s.queries.GetSubCoursePrerequisites(ctx, subCourseID)
if err != nil {
return nil, err
}
prereqs := make([]domain.SubCoursePrerequisite, len(rows))
for i, row := range rows {
prereqs[i] = domain.SubCoursePrerequisite{
ID: row.ID,
SubCourseID: row.SubCourseID,
PrerequisiteSubCourseID: row.PrerequisiteSubCourseID,
CreatedAt: row.CreatedAt.Time,
PrerequisiteTitle: row.PrerequisiteTitle,
PrerequisiteLevel: row.PrerequisiteLevel,
PrerequisiteDisplayOrder: row.PrerequisiteDisplayOrder,
}
}
return prereqs, nil
}
func (s *Store) GetSubCourseDependents(ctx context.Context, prerequisiteSubCourseID int64) ([]domain.SubCourseDependent, error) {
rows, err := s.queries.GetSubCourseDependents(ctx, prerequisiteSubCourseID)
if err != nil {
return nil, err
}
deps := make([]domain.SubCourseDependent, len(rows))
for i, row := range rows {
deps[i] = domain.SubCourseDependent{
ID: row.ID,
SubCourseID: row.SubCourseID,
PrerequisiteSubCourseID: row.PrerequisiteSubCourseID,
CreatedAt: row.CreatedAt.Time,
DependentTitle: row.DependentTitle,
DependentLevel: row.DependentLevel,
}
}
return deps, nil
}
func (s *Store) CountUnmetPrerequisites(ctx context.Context, subCourseID, userID int64) (int64, error) {
return s.queries.CountUnmetPrerequisites(ctx, dbgen.CountUnmetPrerequisitesParams{
SubCourseID: subCourseID,
UserID: userID,
})
}
func (s *Store) DeleteAllPrerequisitesForSubCourse(ctx context.Context, subCourseID int64) error {
return s.queries.DeleteAllPrerequisitesForSubCourse(ctx, subCourseID)
}
func (s *Store) StartSubCourseProgress(ctx context.Context, userID, subCourseID int64) (domain.UserSubCourseProgress, error) {
row, err := s.queries.StartSubCourseProgress(ctx, dbgen.StartSubCourseProgressParams{
UserID: userID,
SubCourseID: subCourseID,
})
if err != nil {
if errors.Is(err, pgx.ErrNoRows) {
return s.GetUserSubCourseProgress(ctx, userID, subCourseID)
}
return domain.UserSubCourseProgress{}, err
}
return mapUserSubCourseProgress(row), nil
}
func (s *Store) UpdateSubCourseProgress(ctx context.Context, userID, subCourseID int64, percentage int16) error {
return s.queries.UpdateSubCourseProgress(ctx, dbgen.UpdateSubCourseProgressParams{
ProgressPercentage: percentage,
UserID: userID,
SubCourseID: subCourseID,
})
}
func (s *Store) CompleteSubCourse(ctx context.Context, userID, subCourseID int64) error {
return s.queries.CompleteSubCourse(ctx, dbgen.CompleteSubCourseParams{
UserID: userID,
SubCourseID: subCourseID,
})
}
func (s *Store) GetUserSubCourseProgress(ctx context.Context, userID, subCourseID int64) (domain.UserSubCourseProgress, error) {
row, err := s.queries.GetUserSubCourseProgress(ctx, dbgen.GetUserSubCourseProgressParams{
UserID: userID,
SubCourseID: subCourseID,
})
if err != nil {
if errors.Is(err, pgx.ErrNoRows) {
return domain.UserSubCourseProgress{}, domain.ErrProgressNotFound
}
return domain.UserSubCourseProgress{}, err
}
return mapUserSubCourseProgress(row), nil
}
func (s *Store) GetUserCourseProgress(ctx context.Context, userID, courseID int64) ([]domain.UserCourseProgressItem, error) {
rows, err := s.queries.GetUserCourseProgress(ctx, dbgen.GetUserCourseProgressParams{
UserID: userID,
CourseID: courseID,
})
if err != nil {
return nil, err
}
items := make([]domain.UserCourseProgressItem, len(rows))
for i, row := range rows {
var startedAt, completedAt *time.Time
if row.StartedAt.Valid {
startedAt = &row.StartedAt.Time
}
if row.CompletedAt.Valid {
completedAt = &row.CompletedAt.Time
}
var updatedAt *time.Time
if row.UpdatedAt.Valid {
updatedAt = &row.UpdatedAt.Time
}
items[i] = domain.UserCourseProgressItem{
ID: row.ID,
UserID: row.UserID,
SubCourseID: row.SubCourseID,
Status: domain.ProgressStatus(row.Status),
ProgressPercentage: row.ProgressPercentage,
StartedAt: startedAt,
CompletedAt: completedAt,
CreatedAt: row.CreatedAt.Time,
UpdatedAt: updatedAt,
SubCourseTitle: row.SubCourseTitle,
SubCourseLevel: row.SubCourseLevel,
SubCourseDisplayOrder: row.SubCourseDisplayOrder,
}
}
return items, nil
}
func (s *Store) GetSubCoursesWithProgressByCourse(ctx context.Context, userID, courseID int64) ([]domain.SubCourseWithProgress, error) {
rows, err := s.queries.GetSubCoursesWithProgressByCourse(ctx, dbgen.GetSubCoursesWithProgressByCourseParams{
UserID: userID,
CourseID: courseID,
})
if err != nil {
return nil, err
}
items := make([]domain.SubCourseWithProgress, len(rows))
for i, row := range rows {
var startedAt, completedAt *time.Time
if row.StartedAt.Valid {
startedAt = &row.StartedAt.Time
}
if row.CompletedAt.Valid {
completedAt = &row.CompletedAt.Time
}
items[i] = domain.SubCourseWithProgress{
SubCourseID: row.SubCourseID,
Title: row.Title,
Description: ptrText(row.Description),
Thumbnail: ptrText(row.Thumbnail),
DisplayOrder: row.DisplayOrder,
Level: row.Level,
IsActive: row.IsActive,
ProgressStatus: domain.ProgressStatus(row.ProgressStatus),
ProgressPercentage: row.ProgressPercentage,
StartedAt: startedAt,
CompletedAt: completedAt,
UnmetPrerequisitesCount: row.UnmetPrerequisitesCount,
IsLocked: row.UnmetPrerequisitesCount > 0,
}
}
return items, nil
}
func mapUserSubCourseProgress(row dbgen.UserSubCourseProgress) domain.UserSubCourseProgress {
var startedAt, completedAt *time.Time
if row.StartedAt.Valid {
startedAt = &row.StartedAt.Time
}
if row.CompletedAt.Valid {
completedAt = &row.CompletedAt.Time
}
var updatedAt *time.Time
if row.UpdatedAt.Valid {
updatedAt = &row.UpdatedAt.Time
}
return domain.UserSubCourseProgress{
ID: row.ID,
UserID: row.UserID,
SubCourseID: row.SubCourseID,
Status: domain.ProgressStatus(row.Status),
ProgressPercentage: row.ProgressPercentage,
StartedAt: startedAt,
CompletedAt: completedAt,
CreatedAt: row.CreatedAt.Time,
UpdatedAt: updatedAt,
}
}