Expose has_practice booleans for LMS and pre-exam hierarchy entities, wire SQL/repository mappings, and regenerate SQLC/Swagger artifacts. Also update the Resend sender display name for outbound emails. Co-authored-by: Cursor <cursoragent@cursor.com>
135 lines
4.1 KiB
Go
135 lines
4.1 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
dbgen "Yimaru-Backend/gen/db"
|
|
"Yimaru-Backend/internal/domain"
|
|
|
|
"github.com/jackc/pgx/v5"
|
|
"github.com/jackc/pgx/v5/pgtype"
|
|
)
|
|
|
|
func examPrepLessonToDomain(l dbgen.ExamPrepUnitModuleLesson) domain.ExamPrepLesson {
|
|
out := domain.ExamPrepLesson{
|
|
ID: l.ID,
|
|
UnitModuleID: l.UnitModuleID,
|
|
Title: l.Title,
|
|
SortOrder: int(l.SortOrder),
|
|
}
|
|
out.VideoURL = fromPgText(l.VideoUrl)
|
|
out.Thumbnail = fromPgText(l.Thumbnail)
|
|
out.Description = fromPgText(l.Description)
|
|
out.CreatedAt = l.CreatedAt.Time
|
|
if l.UpdatedAt.Valid {
|
|
t := l.UpdatedAt.Time
|
|
out.UpdatedAt = &t
|
|
}
|
|
return out
|
|
}
|
|
|
|
func (s *Store) CreateExamPrepUnitModuleLesson(ctx context.Context, unitModuleID int64, input domain.CreateExamPrepLessonInput) (domain.ExamPrepLesson, error) {
|
|
l, err := s.queries.ExamPrepCreateUnitModuleLesson(ctx, dbgen.ExamPrepCreateUnitModuleLessonParams{
|
|
UnitModuleID: unitModuleID,
|
|
Title: input.Title,
|
|
VideoUrl: toPgText(input.VideoURL),
|
|
Thumbnail: toPgText(input.Thumbnail),
|
|
Description: toPgText(input.Description),
|
|
})
|
|
if err != nil {
|
|
return domain.ExamPrepLesson{}, err
|
|
}
|
|
return examPrepLessonToDomain(l), nil
|
|
}
|
|
|
|
func (s *Store) GetExamPrepUnitModuleLessonByID(ctx context.Context, id int64) (domain.ExamPrepLesson, error) {
|
|
l, err := s.queries.ExamPrepGetUnitModuleLessonByID(ctx, id)
|
|
if err != nil {
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
return domain.ExamPrepLesson{}, pgx.ErrNoRows
|
|
}
|
|
return domain.ExamPrepLesson{}, err
|
|
}
|
|
out := examPrepLessonToDomain(dbgen.ExamPrepUnitModuleLesson{
|
|
ID: l.ID,
|
|
UnitModuleID: l.UnitModuleID,
|
|
Title: l.Title,
|
|
VideoUrl: l.VideoUrl,
|
|
Thumbnail: l.Thumbnail,
|
|
Description: l.Description,
|
|
SortOrder: l.SortOrder,
|
|
CreatedAt: l.CreatedAt,
|
|
UpdatedAt: l.UpdatedAt,
|
|
})
|
|
out.HasPractice = l.HasPractice
|
|
return out, nil
|
|
}
|
|
|
|
func (s *Store) ListExamPrepUnitModuleLessonsByUnitModuleID(ctx context.Context, unitModuleID int64, limit, offset int32) ([]domain.ExamPrepLesson, int64, error) {
|
|
rows, err := s.queries.ExamPrepListUnitModuleLessonsByUnitModuleID(ctx, dbgen.ExamPrepListUnitModuleLessonsByUnitModuleIDParams{
|
|
UnitModuleID: unitModuleID,
|
|
Limit: limit,
|
|
Offset: offset,
|
|
})
|
|
if err != nil {
|
|
return nil, 0, err
|
|
}
|
|
if len(rows) == 0 {
|
|
return []domain.ExamPrepLesson{}, 0, nil
|
|
}
|
|
var total int64
|
|
out := make([]domain.ExamPrepLesson, 0, len(rows))
|
|
for i, r := range rows {
|
|
if i == 0 {
|
|
total = r.TotalCount
|
|
}
|
|
item := examPrepLessonToDomain(dbgen.ExamPrepUnitModuleLesson{
|
|
ID: r.ID,
|
|
UnitModuleID: r.UnitModuleID,
|
|
Title: r.Title,
|
|
VideoUrl: r.VideoUrl,
|
|
Thumbnail: r.Thumbnail,
|
|
Description: r.Description,
|
|
SortOrder: r.SortOrder,
|
|
CreatedAt: r.CreatedAt,
|
|
UpdatedAt: r.UpdatedAt,
|
|
})
|
|
item.HasPractice = r.HasPractice
|
|
out = append(out, item)
|
|
}
|
|
return out, total, nil
|
|
}
|
|
|
|
func (s *Store) ListExamPrepUnitModuleLessonIDsByUnitModule(ctx context.Context, unitModuleID int64) ([]int64, error) {
|
|
return s.queries.ExamPrepListUnitModuleLessonIDsByUnitModule(ctx, unitModuleID)
|
|
}
|
|
|
|
func (s *Store) UpdateExamPrepUnitModuleLesson(ctx context.Context, id int64, input domain.UpdateExamPrepLessonInput) (domain.ExamPrepLesson, error) {
|
|
var titleText pgtype.Text
|
|
if input.Title != nil {
|
|
titleText = pgtype.Text{String: *input.Title, Valid: true}
|
|
} else {
|
|
titleText = pgtype.Text{Valid: false}
|
|
}
|
|
l, err := s.queries.ExamPrepUpdateUnitModuleLesson(ctx, dbgen.ExamPrepUpdateUnitModuleLessonParams{
|
|
ID: id,
|
|
Title: titleText,
|
|
VideoUrl: optionalTextUpdate(input.VideoURL),
|
|
Thumbnail: optionalTextUpdate(input.Thumbnail),
|
|
Description: optionalTextUpdate(input.Description),
|
|
SortOrder: optionalInt4Update(input.SortOrder),
|
|
})
|
|
if err != nil {
|
|
if errors.Is(err, pgx.ErrNoRows) {
|
|
return domain.ExamPrepLesson{}, pgx.ErrNoRows
|
|
}
|
|
return domain.ExamPrepLesson{}, err
|
|
}
|
|
return examPrepLessonToDomain(l), nil
|
|
}
|
|
|
|
func (s *Store) DeleteExamPrepUnitModuleLesson(ctx context.Context, id int64) error {
|
|
return s.queries.ExamPrepDeleteUnitModuleLesson(ctx, id)
|
|
}
|