feat: add progression readiness api
This commit is contained in:
@@ -10,13 +10,15 @@ import (
|
||||
"tutor/internal/config"
|
||||
"tutor/internal/interview"
|
||||
"tutor/internal/learnermemory"
|
||||
"tutor/internal/progression"
|
||||
"tutor/internal/workflows"
|
||||
)
|
||||
|
||||
func TestDiagnosticHTTPFlow(t *testing.T) {
|
||||
memory := learnermemory.NewService(learnermemory.NewMemoryStore())
|
||||
service := interview.NewService(interview.NewMemoryStore(), workflows.NewStubRunner(), memory)
|
||||
handler := NewHandler(config.Config{Environment: "test", ModelKey: "deepseek-v4-flash"}, service, memory)
|
||||
progress := progression.NewService(memory)
|
||||
handler := NewHandler(config.Config{Environment: "test", ModelKey: "deepseek-v4-flash"}, service, memory, progress)
|
||||
routes := handler.Routes()
|
||||
|
||||
createBody := bytes.NewBufferString(`{
|
||||
@@ -93,4 +95,20 @@ func TestDiagnosticHTTPFlow(t *testing.T) {
|
||||
if len(snapshot.Mastery) == 0 {
|
||||
t.Fatal("expected mastery entries")
|
||||
}
|
||||
|
||||
readinessReq := httptest.NewRequest(http.MethodGet, "/api/v1/learners/user-1/readiness-map", nil)
|
||||
readinessRec := httptest.NewRecorder()
|
||||
routes.ServeHTTP(readinessRec, readinessReq)
|
||||
|
||||
if readinessRec.Code != http.StatusOK {
|
||||
t.Fatalf("readiness status = %d, body = %s", readinessRec.Code, readinessRec.Body.String())
|
||||
}
|
||||
|
||||
challengeReq := httptest.NewRequest(http.MethodGet, "/api/v1/learners/user-1/next-challenge", nil)
|
||||
challengeRec := httptest.NewRecorder()
|
||||
routes.ServeHTTP(challengeRec, challengeReq)
|
||||
|
||||
if challengeRec.Code != http.StatusOK {
|
||||
t.Fatalf("challenge status = %d, body = %s", challengeRec.Code, challengeRec.Body.String())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,19 +7,27 @@ import (
|
||||
"tutor/internal/config"
|
||||
"tutor/internal/interview"
|
||||
"tutor/internal/learnermemory"
|
||||
"tutor/internal/progression"
|
||||
)
|
||||
|
||||
type Handler struct {
|
||||
cfg config.Config
|
||||
diagnostic *interview.Service
|
||||
memory *learnermemory.Service
|
||||
progress *progression.Service
|
||||
}
|
||||
|
||||
func NewHandler(cfg config.Config, diagnostic *interview.Service, memory *learnermemory.Service) Handler {
|
||||
func NewHandler(
|
||||
cfg config.Config,
|
||||
diagnostic *interview.Service,
|
||||
memory *learnermemory.Service,
|
||||
progress *progression.Service,
|
||||
) Handler {
|
||||
return Handler{
|
||||
cfg: cfg,
|
||||
diagnostic: diagnostic,
|
||||
memory: memory,
|
||||
progress: progress,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +38,8 @@ func (h Handler) Routes() http.Handler {
|
||||
mux.HandleFunc("GET /api/v1/diagnostic-sessions/{id}", h.getDiagnosticSession)
|
||||
mux.HandleFunc("POST /api/v1/diagnostic-sessions/{id}/answers", h.submitDiagnosticAnswer)
|
||||
mux.HandleFunc("GET /api/v1/learners/{userID}/memory", h.getLearnerMemory)
|
||||
mux.HandleFunc("GET /api/v1/learners/{userID}/readiness-map", h.getReadinessMap)
|
||||
mux.HandleFunc("GET /api/v1/learners/{userID}/next-challenge", h.getNextChallenge)
|
||||
return mux
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"tutor/internal/config"
|
||||
"tutor/internal/interview"
|
||||
"tutor/internal/learnermemory"
|
||||
"tutor/internal/progression"
|
||||
"tutor/internal/workflows"
|
||||
)
|
||||
|
||||
@@ -19,7 +20,8 @@ func TestHealth(t *testing.T) {
|
||||
}
|
||||
memory := learnermemory.NewService(learnermemory.NewMemoryStore())
|
||||
service := interview.NewService(interview.NewMemoryStore(), workflows.NewStubRunner(), memory)
|
||||
handler := NewHandler(cfg, service, memory)
|
||||
progress := progression.NewService(memory)
|
||||
handler := NewHandler(cfg, service, memory, progress)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/healthz", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
46
internal/httpapi/progression.go
Normal file
46
internal/httpapi/progression.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package httpapi
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"tutor/internal/learnermemory"
|
||||
)
|
||||
|
||||
func (h Handler) getReadinessMap(w http.ResponseWriter, r *http.Request) {
|
||||
if h.progress == nil {
|
||||
writeError(w, http.StatusNotFound, "progression not configured")
|
||||
return
|
||||
}
|
||||
|
||||
readiness, err := h.progress.ReadinessMap(r.PathValue("userID"))
|
||||
if errors.Is(err, learnermemory.ErrProfileNotFound) {
|
||||
writeError(w, http.StatusNotFound, "learner memory not found")
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
writeError(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
writeJSON(w, http.StatusOK, readiness)
|
||||
}
|
||||
|
||||
func (h Handler) getNextChallenge(w http.ResponseWriter, r *http.Request) {
|
||||
if h.progress == nil {
|
||||
writeError(w, http.StatusNotFound, "progression not configured")
|
||||
return
|
||||
}
|
||||
|
||||
challenge, err := h.progress.NextChallenge(r.PathValue("userID"))
|
||||
if errors.Is(err, learnermemory.ErrProfileNotFound) {
|
||||
writeError(w, http.StatusNotFound, "learner memory not found")
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
writeError(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
writeJSON(w, http.StatusOK, challenge)
|
||||
}
|
||||
Reference in New Issue
Block a user