93 lines
2.4 KiB
Go
93 lines
2.4 KiB
Go
package modules
|
|
|
|
import (
|
|
"Yimaru-Backend/internal/domain"
|
|
"Yimaru-Backend/internal/ports"
|
|
"Yimaru-Backend/internal/services/courses"
|
|
"context"
|
|
"errors"
|
|
|
|
"github.com/jackc/pgx/v5"
|
|
)
|
|
|
|
var ErrModuleNotFound = errors.New("module not found")
|
|
|
|
type Service struct {
|
|
modules ports.ModuleStore
|
|
courses ports.CourseStore
|
|
}
|
|
|
|
func NewService(modules ports.ModuleStore, courses ports.CourseStore) *Service {
|
|
return &Service{modules: modules, courses: courses}
|
|
}
|
|
|
|
func (s *Service) getCourseOrErr(ctx context.Context, courseID int64) (domain.Course, error) {
|
|
c, err := s.courses.GetCourseByID(ctx, courseID)
|
|
if err != nil {
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
return domain.Course{}, courses.ErrCourseNotFound
|
|
}
|
|
return domain.Course{}, err
|
|
}
|
|
return c, nil
|
|
}
|
|
|
|
// Create loads the course and stores program_id from it (parent program is not taken from the URL).
|
|
func (s *Service) Create(ctx context.Context, courseID int64, input domain.CreateModuleInput) (domain.Module, error) {
|
|
c, err := s.getCourseOrErr(ctx, courseID)
|
|
if err != nil {
|
|
return domain.Module{}, err
|
|
}
|
|
return s.modules.CreateModule(ctx, c.ProgramID, courseID, input)
|
|
}
|
|
|
|
func (s *Service) GetByID(ctx context.Context, id int64) (domain.Module, error) {
|
|
m, err := s.modules.GetModuleByID(ctx, id)
|
|
if err != nil {
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
return domain.Module{}, ErrModuleNotFound
|
|
}
|
|
return domain.Module{}, err
|
|
}
|
|
return m, nil
|
|
}
|
|
|
|
// ListByCourse loads the course and lists modules for its program_id and course_id.
|
|
func (s *Service) ListByCourse(ctx context.Context, courseID int64, limit, offset int32) ([]domain.Module, int64, error) {
|
|
c, err := s.getCourseOrErr(ctx, courseID)
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
if limit <= 0 {
|
|
limit = 20
|
|
}
|
|
if limit > 200 {
|
|
limit = 200
|
|
}
|
|
if offset < 0 {
|
|
offset = 0
|
|
}
|
|
return s.modules.ListModulesByProgramAndCourse(ctx, c.ProgramID, courseID, limit, offset)
|
|
}
|
|
|
|
func (s *Service) Update(ctx context.Context, id int64, input domain.UpdateModuleInput) (domain.Module, error) {
|
|
m, err := s.modules.UpdateModule(ctx, id, input)
|
|
if err != nil {
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
return domain.Module{}, ErrModuleNotFound
|
|
}
|
|
return domain.Module{}, err
|
|
}
|
|
return m, nil
|
|
}
|
|
|
|
func (s *Service) Delete(ctx context.Context, id int64) error {
|
|
if _, err := s.modules.GetModuleByID(ctx, id); err != nil {
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
return ErrModuleNotFound
|
|
}
|
|
return err
|
|
}
|
|
return s.modules.DeleteModule(ctx, id)
|
|
}
|