filter by learning_types and course_thematics
This commit is contained in:
@ -3,6 +3,7 @@ package main
|
|||||||
import (
|
import (
|
||||||
"log/slog"
|
"log/slog"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.loyso.art/frx/kurious/assets/kurious"
|
"git.loyso.art/frx/kurious/assets/kurious"
|
||||||
@ -13,6 +14,23 @@ import (
|
|||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
pathParamLearningType = "learning_type"
|
||||||
|
pathParamThematicType = "thematic_type"
|
||||||
|
)
|
||||||
|
|
||||||
|
func makePathTemplate(params ...string) string {
|
||||||
|
var sb strings.Builder
|
||||||
|
for _, param := range params {
|
||||||
|
sb.WriteRune('/')
|
||||||
|
sb.WriteRune('{')
|
||||||
|
sb.WriteString(param)
|
||||||
|
sb.WriteRune('}')
|
||||||
|
}
|
||||||
|
|
||||||
|
return sb.String()
|
||||||
|
}
|
||||||
|
|
||||||
func setupHTTP(cfg config.HTTP, srv xhttp.Server, log *slog.Logger) *http.Server {
|
func setupHTTP(cfg config.HTTP, srv xhttp.Server, log *slog.Logger) *http.Server {
|
||||||
router := mux.NewRouter()
|
router := mux.NewRouter()
|
||||||
|
|
||||||
@ -23,8 +41,12 @@ func setupHTTP(cfg config.HTTP, srv xhttp.Server, log *slog.Logger) *http.Server
|
|||||||
router.HandleFunc("/updatedesc", coursesAPI.UdpateDescription).Methods(http.MethodPost)
|
router.HandleFunc("/updatedesc", coursesAPI.UdpateDescription).Methods(http.MethodPost)
|
||||||
coursesRouter := router.PathPrefix("/courses").Subrouter()
|
coursesRouter := router.PathPrefix("/courses").Subrouter()
|
||||||
coursesRouter.HandleFunc("/", coursesAPI.List).Methods(http.MethodGet)
|
coursesRouter.HandleFunc("/", coursesAPI.List).Methods(http.MethodGet)
|
||||||
|
coursesListLearningOnlyPath := makePathTemplate(pathParamLearningType)
|
||||||
|
coursesRouter.HandleFunc(coursesListLearningOnlyPath, coursesAPI.List).Methods(http.MethodGet)
|
||||||
|
coursesListFullPath := makePathTemplate(pathParamLearningType, pathParamThematicType)
|
||||||
|
coursesRouter.HandleFunc(coursesListFullPath, coursesAPI.List).Methods(http.MethodGet)
|
||||||
|
|
||||||
courseRouter := coursesRouter.PathPrefix("/{course_id}").Subrouter()
|
courseRouter := router.PathPrefix("/course").PathPrefix("/{course_id}").Subrouter()
|
||||||
courseRouter.HandleFunc("/", coursesAPI.Get).Methods(http.MethodGet)
|
courseRouter.HandleFunc("/", coursesAPI.Get).Methods(http.MethodGet)
|
||||||
courseRouter.HandleFunc("/short", coursesAPI.GetShort).Methods(http.MethodGet)
|
courseRouter.HandleFunc("/short", coursesAPI.GetShort).Methods(http.MethodGet)
|
||||||
courseRouter.HandleFunc("/editdesc", coursesAPI.RenderEditDescription).Methods(http.MethodGet)
|
courseRouter.HandleFunc("/editdesc", coursesAPI.RenderEditDescription).Methods(http.MethodGet)
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import (
|
|||||||
"git.loyso.art/frx/kurious/internal/kurious/adapters"
|
"git.loyso.art/frx/kurious/internal/kurious/adapters"
|
||||||
xhttp "git.loyso.art/frx/kurious/internal/kurious/ports/http"
|
xhttp "git.loyso.art/frx/kurious/internal/kurious/ports/http"
|
||||||
"git.loyso.art/frx/kurious/internal/kurious/service"
|
"git.loyso.art/frx/kurious/internal/kurious/service"
|
||||||
|
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -88,26 +89,30 @@ func app(ctx context.Context) error {
|
|||||||
slog.String("addr", httpServer.Addr),
|
slog.String("addr", httpServer.Addr),
|
||||||
)
|
)
|
||||||
|
|
||||||
err := httpServer.ListenAndServe()
|
if err := httpServer.ListenAndServe(); err != nil {
|
||||||
if err != nil {
|
|
||||||
if !errors.Is(err, http.ErrServerClosed) {
|
if !errors.Is(err, http.ErrServerClosed) {
|
||||||
return fmt.Errorf("listening http: %w", err)
|
return fmt.Errorf("listening http: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
eg.Go(func() error {
|
eg.Go(func() error {
|
||||||
<-egctx.Done()
|
<-egctx.Done()
|
||||||
|
|
||||||
xcontext.LogInfo(ctx, log, "trying to shutdown http")
|
xcontext.LogInfo(ctx, log, "trying to shutdown http")
|
||||||
|
|
||||||
sdctx, sdcancel := context.WithTimeout(context.Background(), time.Second*10)
|
sdctx, sdcancel := context.WithTimeout(context.Background(), time.Second*10)
|
||||||
defer sdcancel()
|
defer sdcancel()
|
||||||
|
|
||||||
err := httpServer.Shutdown(sdctx)
|
err := httpServer.Shutdown(sdctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("shutting down the server: %w", err)
|
return fmt.Errorf("shutting down the server: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
xcontext.LogInfo(ctx, log, "server closed successfuly")
|
xcontext.LogInfo(ctx, log, "server closed successfuly")
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -179,6 +179,8 @@ func (r *ydbCourseRepository) List(
|
|||||||
return result, fmt.Errorf("rendering query params: %w", err)
|
return result, fmt.Errorf("rendering query params: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xcontext.LogInfo(ctx, r.log, "query prepared", slog.String("query", query), slog.String("args", tableParamOptsToString(opts...)))
|
||||||
|
|
||||||
courses := make([]domain.Course, 0, 1_000)
|
courses := make([]domain.Course, 0, 1_000)
|
||||||
readTx := table.TxControl(
|
readTx := table.TxControl(
|
||||||
table.BeginTx(
|
table.BeginTx(
|
||||||
@ -192,7 +194,7 @@ func (r *ydbCourseRepository) List(
|
|||||||
func(ctx context.Context, s table.Session) error {
|
func(ctx context.Context, s table.Session) error {
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
defer func() {
|
defer func() {
|
||||||
since := time.Since(start)
|
since := time.Since(start).Truncate(time.Millisecond)
|
||||||
xcontext.LogInfo(
|
xcontext.LogInfo(
|
||||||
ctx, r.log,
|
ctx, r.log,
|
||||||
"executed query",
|
"executed query",
|
||||||
@ -242,6 +244,156 @@ func (r *ydbCourseRepository) List(
|
|||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *ydbCourseRepository) ListLearningTypes(
|
||||||
|
ctx context.Context,
|
||||||
|
) (result domain.ListLearningTypeResult, err error) {
|
||||||
|
const queryName = "list_learning_type"
|
||||||
|
const querySelect = `SELECT DISTINCT learning_type FROM courses;`
|
||||||
|
|
||||||
|
readTx := table.TxControl(
|
||||||
|
table.BeginTx(
|
||||||
|
table.WithOnlineReadOnly(),
|
||||||
|
),
|
||||||
|
table.CommitTx(),
|
||||||
|
)
|
||||||
|
|
||||||
|
err = r.db.Table().Do(
|
||||||
|
ctx,
|
||||||
|
func(ctx context.Context, s table.Session) error {
|
||||||
|
start := time.Now()
|
||||||
|
defer func() {
|
||||||
|
since := time.Since(start).Truncate(time.Millisecond)
|
||||||
|
xcontext.LogInfo(
|
||||||
|
ctx, r.log,
|
||||||
|
"executed query",
|
||||||
|
slog.String("name", queryName),
|
||||||
|
slog.Duration("elapsed", since),
|
||||||
|
)
|
||||||
|
}()
|
||||||
|
|
||||||
|
_, res, err := s.Execute(
|
||||||
|
ctx, readTx, querySelect, table.NewQueryParameters(),
|
||||||
|
options.WithCollectStatsModeNone(),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("executing query: %w", err)
|
||||||
|
}
|
||||||
|
if !res.NextResultSet(ctx) || !res.HasNextRow() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for res.NextRow() {
|
||||||
|
var learningTypeID string
|
||||||
|
if err = res.Scan(&learningTypeID); err != nil {
|
||||||
|
return fmt.Errorf("scanning row: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
result.LearningTypeIDs = append(result.LearningTypeIDs, learningTypeID)
|
||||||
|
}
|
||||||
|
if err = res.Err(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
xcontext.LogDebug(ctx, r.log, "scanned rows", slog.Int("count", len(result.LearningTypeIDs)))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
table.WithIdempotent(),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ydbCourseRepository) ListCourseThematics(
|
||||||
|
ctx context.Context,
|
||||||
|
params domain.ListCourseThematicsParams,
|
||||||
|
) (result domain.ListCourseThematicsResult, err error) {
|
||||||
|
const queryName = "list_course_thematics"
|
||||||
|
|
||||||
|
qtParams := queryTemplateParams{
|
||||||
|
Fields: "DISTINCT course_thematic",
|
||||||
|
Table: "courses",
|
||||||
|
Declares: []queryTemplateDeclaration{},
|
||||||
|
Conditions: []string{},
|
||||||
|
}
|
||||||
|
|
||||||
|
learningTypeValue := types.TextValue(params.LearningTypeID)
|
||||||
|
d := queryTemplateDeclaration{
|
||||||
|
Name: "course_thematic",
|
||||||
|
Type: learningTypeValue.Type().String(),
|
||||||
|
}
|
||||||
|
qtParams.Declares = append(qtParams.Declares, d)
|
||||||
|
qtParams.Conditions = append(qtParams.Conditions, d.Name+"="+d.Arg())
|
||||||
|
|
||||||
|
opts := []table.ParameterOption{
|
||||||
|
table.ValueParam(d.Arg(), learningTypeValue),
|
||||||
|
}
|
||||||
|
|
||||||
|
query, err := qtParams.render()
|
||||||
|
if err != nil {
|
||||||
|
return result, fmt.Errorf("rendering query params: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
readTx := table.TxControl(
|
||||||
|
table.BeginTx(
|
||||||
|
table.WithOnlineReadOnly(),
|
||||||
|
),
|
||||||
|
table.CommitTx(),
|
||||||
|
)
|
||||||
|
|
||||||
|
err = r.db.Table().Do(
|
||||||
|
ctx,
|
||||||
|
func(ctx context.Context, s table.Session) error {
|
||||||
|
start := time.Now()
|
||||||
|
defer func() {
|
||||||
|
since := time.Since(start).Truncate(time.Millisecond)
|
||||||
|
xcontext.LogInfo(
|
||||||
|
ctx, r.log,
|
||||||
|
"executed query",
|
||||||
|
slog.String("name", queryName),
|
||||||
|
slog.Duration("elapsed", since),
|
||||||
|
)
|
||||||
|
}()
|
||||||
|
|
||||||
|
_, res, err := s.Execute(
|
||||||
|
ctx, readTx, query, table.NewQueryParameters(opts...),
|
||||||
|
options.WithCollectStatsModeNone(),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("executing query: %w", err)
|
||||||
|
}
|
||||||
|
if !res.NextResultSet(ctx) || !res.HasNextRow() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for res.NextRow() {
|
||||||
|
var courseThematicID string
|
||||||
|
if err = res.Scan(&courseThematicID); err != nil {
|
||||||
|
return fmt.Errorf("scanning row: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
result.CourseThematicIDs = append(result.CourseThematicIDs, courseThematicID)
|
||||||
|
}
|
||||||
|
if err = res.Err(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
xcontext.LogDebug(ctx, r.log, "scanned rows", slog.Int("count", len(result.CourseThematicIDs)))
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
table.WithIdempotent(),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *ydbCourseRepository) Get(
|
func (r *ydbCourseRepository) Get(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
id string,
|
id string,
|
||||||
@ -735,15 +887,16 @@ func (p queryTemplateParams) render() (string, error) {
|
|||||||
const queryTemplateSelect = `{{ range .Declares }}DECLARE ${{.Name}} AS {{.Type}};{{end}}
|
const queryTemplateSelect = `{{ range .Declares }}DECLARE ${{.Name}} AS {{.Type}};{{end}}
|
||||||
SELECT {{.Fields}}
|
SELECT {{.Fields}}
|
||||||
FROM {{.Table}}
|
FROM {{.Table}}
|
||||||
WHERE {{ range .Conditions }}{{.}}{{end}}
|
WHERE 1=1 {{ range .Conditions }} AND {{.}} {{ end }}
|
||||||
{{.Suffix}}`
|
{{.Suffix}}`
|
||||||
|
|
||||||
var querySelect = template.Must(template.New("").Parse(queryTemplateSelect))
|
var querySelect = template.Must(template.New("").Parse(queryTemplateSelect))
|
||||||
|
|
||||||
// func tableParamOptsToString(in ...table.ParameterOption) string {
|
func tableParamOptsToString(in ...table.ParameterOption) string {
|
||||||
// var sb strings.Builder
|
var sb strings.Builder
|
||||||
// for _, opt := range in {
|
for _, opt := range in {
|
||||||
// sb.WriteString(opt.Name() + "(" + opt.Value().Type().String() + ");")
|
sb.WriteString(opt.Name() + ":" + opt.Value().Yql() + ";")
|
||||||
// }
|
// sb.WriteString(opt.Name() + " (" + opt.Value().Type().String() + "); ")
|
||||||
// return sb.String()
|
}
|
||||||
// }
|
return sb.String()
|
||||||
|
}
|
||||||
|
|||||||
@ -13,8 +13,10 @@ type Commands struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Queries struct {
|
type Queries struct {
|
||||||
GetCourse query.GetCourseHandler
|
GetCourse query.GetCourseHandler
|
||||||
ListCourses query.ListCourseHandler
|
ListCourses query.ListCourseHandler
|
||||||
|
ListLearningTypes query.ListLearningTypesHandler
|
||||||
|
ListCourseThematics query.ListCourseThematicsHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
type Application struct {
|
type Application struct {
|
||||||
|
|||||||
@ -16,15 +16,18 @@ type GetCourse struct {
|
|||||||
type GetCourseHandler decorator.QueryHandler[GetCourse, domain.Course]
|
type GetCourseHandler decorator.QueryHandler[GetCourse, domain.Course]
|
||||||
|
|
||||||
type getCourseHandler struct {
|
type getCourseHandler struct {
|
||||||
repo domain.CourseRepository
|
repo domain.CourseRepository
|
||||||
|
mapper domain.CourseMapper
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGetCourseHandler(
|
func NewGetCourseHandler(
|
||||||
repo domain.CourseRepository,
|
repo domain.CourseRepository,
|
||||||
|
mapper domain.CourseMapper,
|
||||||
log *slog.Logger,
|
log *slog.Logger,
|
||||||
) GetCourseHandler {
|
) GetCourseHandler {
|
||||||
h := getCourseHandler{
|
h := getCourseHandler{
|
||||||
repo: repo,
|
repo: repo,
|
||||||
|
mapper: mapper,
|
||||||
}
|
}
|
||||||
return decorator.AddQueryDecorators(h, log)
|
return decorator.AddQueryDecorators(h, log)
|
||||||
}
|
}
|
||||||
@ -35,5 +38,8 @@ func (h getCourseHandler) Handle(ctx context.Context, query GetCourse) (domain.C
|
|||||||
return domain.Course{}, fmt.Errorf("getting course: %w", err)
|
return domain.Course{}, fmt.Errorf("getting course: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
course.LearningType = h.mapper.LearningTypeNameByID(course.LearningTypeID)
|
||||||
|
course.Thematic = h.mapper.CourseThematicNameByID(course.ThematicID)
|
||||||
|
|
||||||
return course, nil
|
return course, nil
|
||||||
}
|
}
|
||||||
|
|||||||
62
internal/kurious/app/query/listcoursethematics.go
Normal file
62
internal/kurious/app/query/listcoursethematics.go
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
package query
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
|
|
||||||
|
"git.loyso.art/frx/kurious/internal/common/decorator"
|
||||||
|
"git.loyso.art/frx/kurious/internal/kurious/domain"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ListCourseThematics struct {
|
||||||
|
LearningTypeID string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CourseThematic struct {
|
||||||
|
ID string
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListCourseThematicsResult struct {
|
||||||
|
CourseThematics []CourseThematic
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListCourseThematicsHandler decorator.QueryHandler[ListCourseThematics, ListCourseThematicsResult]
|
||||||
|
|
||||||
|
type listCourseThematicsHandler struct {
|
||||||
|
repo domain.CourseRepository
|
||||||
|
mapper domain.CourseMapper
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewListCourseThematicsHandler(
|
||||||
|
repo domain.CourseRepository,
|
||||||
|
mapper domain.CourseMapper,
|
||||||
|
log *slog.Logger,
|
||||||
|
) ListCourseThematicsHandler {
|
||||||
|
h := listCourseThematicsHandler{
|
||||||
|
repo: repo,
|
||||||
|
mapper: mapper,
|
||||||
|
}
|
||||||
|
|
||||||
|
return decorator.AddQueryDecorators(h, log)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h listCourseThematicsHandler) Handle(ctx context.Context, query ListCourseThematics) (out ListCourseThematicsResult, err error) {
|
||||||
|
result, err := h.repo.ListCourseThematics(ctx, domain.ListCourseThematicsParams{
|
||||||
|
LearningTypeID: query.LearningTypeID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return out, fmt.Errorf("listing course thematics from repo: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
out.CourseThematics = make([]CourseThematic, 0, len(result.CourseThematicIDs))
|
||||||
|
for _, ct := range result.CourseThematicIDs {
|
||||||
|
var item CourseThematic
|
||||||
|
item.ID = ct
|
||||||
|
item.Name = h.mapper.CourseThematicNameByID(ct)
|
||||||
|
out.CourseThematics = append(out.CourseThematics, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
58
internal/kurious/app/query/listlearningtypes.go
Normal file
58
internal/kurious/app/query/listlearningtypes.go
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
package query
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"log/slog"
|
||||||
|
|
||||||
|
"git.loyso.art/frx/kurious/internal/common/decorator"
|
||||||
|
"git.loyso.art/frx/kurious/internal/kurious/domain"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ListLearningTypes struct{}
|
||||||
|
|
||||||
|
type LearningType struct {
|
||||||
|
ID string
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListLearningTypesResult struct {
|
||||||
|
LearningTypes []LearningType
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListLearningTypesHandler decorator.QueryHandler[ListLearningTypes, ListLearningTypesResult]
|
||||||
|
|
||||||
|
type listLearningTypesHandler struct {
|
||||||
|
repo domain.CourseRepository
|
||||||
|
mapper domain.CourseMapper
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewListLearningTypesHandler(
|
||||||
|
repo domain.CourseRepository,
|
||||||
|
mapper domain.CourseMapper,
|
||||||
|
log *slog.Logger,
|
||||||
|
) ListLearningTypesHandler {
|
||||||
|
h := listLearningTypesHandler{
|
||||||
|
repo: repo,
|
||||||
|
mapper: mapper,
|
||||||
|
}
|
||||||
|
|
||||||
|
return decorator.AddQueryDecorators(h, log)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h listLearningTypesHandler) Handle(ctx context.Context, query ListLearningTypes) (out ListLearningTypesResult, err error) {
|
||||||
|
result, err := h.repo.ListLearningTypes(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return out, fmt.Errorf("listing learning types from repo: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
out.LearningTypes = make([]LearningType, 0, len(result.LearningTypeIDs))
|
||||||
|
for _, lt := range result.LearningTypeIDs {
|
||||||
|
var item LearningType
|
||||||
|
item.ID = lt
|
||||||
|
item.Name = h.mapper.LearningTypeNameByID(lt)
|
||||||
|
out.LearningTypes = append(out.LearningTypes, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
@ -39,10 +39,24 @@ type ListCoursesResult struct {
|
|||||||
NextPageToken string
|
NextPageToken string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ListLearningTypeResult struct {
|
||||||
|
LearningTypeIDs []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListCourseThematicsParams struct {
|
||||||
|
LearningTypeID string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ListCourseThematicsResult struct {
|
||||||
|
CourseThematicIDs []string
|
||||||
|
}
|
||||||
|
|
||||||
//go:generate mockery --name CourseRepository
|
//go:generate mockery --name CourseRepository
|
||||||
type CourseRepository interface {
|
type CourseRepository interface {
|
||||||
// List courses by specifid parameters.
|
// List courses by specifid parameters.
|
||||||
List(ctx context.Context, params ListCoursesParams) (ListCoursesResult, error)
|
List(context.Context, ListCoursesParams) (ListCoursesResult, error)
|
||||||
|
ListLearningTypes(context.Context) (ListLearningTypeResult, error)
|
||||||
|
ListCourseThematics(context.Context, ListCourseThematicsParams) (ListCourseThematicsResult, error)
|
||||||
// Get course by id.
|
// Get course by id.
|
||||||
// Should return ErrNotFound in case course not found.
|
// Should return ErrNotFound in case course not found.
|
||||||
Get(ctx context.Context, id string) (Course, error)
|
Get(ctx context.Context, id string) (Course, error)
|
||||||
|
|||||||
@ -50,9 +50,9 @@ func parseListCoursesParams(r *http.Request) (out listCoursesParams, err error)
|
|||||||
return out, err
|
return out, err
|
||||||
}
|
}
|
||||||
|
|
||||||
query := r.URL.Query()
|
vars := mux.Vars(r)
|
||||||
out.learningType = query.Get("category")
|
out.learningType = vars["learning_type"]
|
||||||
out.courseThematic = query.Get("type")
|
out.courseThematic = vars["thematic_type"]
|
||||||
|
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,8 +43,10 @@ func NewApplication(ctx context.Context, cfg ApplicationConfig, mapper domain.Co
|
|||||||
UpdateCourseDescription: command.NewUpdateCourseDescriptionHandler(courseadapter, log),
|
UpdateCourseDescription: command.NewUpdateCourseDescriptionHandler(courseadapter, log),
|
||||||
},
|
},
|
||||||
Queries: app.Queries{
|
Queries: app.Queries{
|
||||||
GetCourse: query.NewGetCourseHandler(courseadapter, log),
|
ListCourses: query.NewListCourseHandler(courseadapter, mapper, log),
|
||||||
ListCourses: query.NewListCourseHandler(courseadapter, mapper, log),
|
ListLearningTypes: query.NewListLearningTypesHandler(courseadapter, mapper, log),
|
||||||
|
ListCourseThematics: query.NewListCourseThematicsHandler(courseadapter, mapper, log),
|
||||||
|
GetCourse: query.NewGetCourseHandler(courseadapter, mapper, log),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user