feat: add learner memory ingestion
This commit is contained in:
@@ -9,12 +9,14 @@ import (
|
||||
|
||||
"tutor/internal/config"
|
||||
"tutor/internal/interview"
|
||||
"tutor/internal/learnermemory"
|
||||
"tutor/internal/workflows"
|
||||
)
|
||||
|
||||
func TestDiagnosticHTTPFlow(t *testing.T) {
|
||||
service := interview.NewService(interview.NewMemoryStore(), workflows.NewStubRunner())
|
||||
handler := NewHandler(config.Config{Environment: "test", ModelKey: "deepseek-v4-flash"}, service)
|
||||
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)
|
||||
routes := handler.Routes()
|
||||
|
||||
createBody := bytes.NewBufferString(`{
|
||||
@@ -73,4 +75,22 @@ func TestDiagnosticHTTPFlow(t *testing.T) {
|
||||
if len(loaded.Answers) != 1 {
|
||||
t.Fatalf("answers = %d, want 1", len(loaded.Answers))
|
||||
}
|
||||
|
||||
memoryReq := httptest.NewRequest(http.MethodGet, "/api/v1/learners/user-1/memory", nil)
|
||||
memoryRec := httptest.NewRecorder()
|
||||
routes.ServeHTTP(memoryRec, memoryReq)
|
||||
|
||||
if memoryRec.Code != http.StatusOK {
|
||||
t.Fatalf("memory status = %d, body = %s", memoryRec.Code, memoryRec.Body.String())
|
||||
}
|
||||
var snapshot learnermemory.Snapshot
|
||||
if err := json.NewDecoder(memoryRec.Body).Decode(&snapshot); err != nil {
|
||||
t.Fatalf("decode memory response: %v", err)
|
||||
}
|
||||
if snapshot.Profile.UserID != "user-1" {
|
||||
t.Fatalf("memory profile user = %q", snapshot.Profile.UserID)
|
||||
}
|
||||
if len(snapshot.Mastery) == 0 {
|
||||
t.Fatal("expected mastery entries")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,17 +6,20 @@ import (
|
||||
|
||||
"tutor/internal/config"
|
||||
"tutor/internal/interview"
|
||||
"tutor/internal/learnermemory"
|
||||
)
|
||||
|
||||
type Handler struct {
|
||||
cfg config.Config
|
||||
diagnostic *interview.Service
|
||||
memory *learnermemory.Service
|
||||
}
|
||||
|
||||
func NewHandler(cfg config.Config, diagnostic *interview.Service) Handler {
|
||||
func NewHandler(cfg config.Config, diagnostic *interview.Service, memory *learnermemory.Service) Handler {
|
||||
return Handler{
|
||||
cfg: cfg,
|
||||
diagnostic: diagnostic,
|
||||
memory: memory,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +29,7 @@ func (h Handler) Routes() http.Handler {
|
||||
mux.HandleFunc("POST /api/v1/diagnostic-sessions", h.createDiagnosticSession)
|
||||
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)
|
||||
return mux
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import (
|
||||
|
||||
"tutor/internal/config"
|
||||
"tutor/internal/interview"
|
||||
"tutor/internal/learnermemory"
|
||||
"tutor/internal/workflows"
|
||||
)
|
||||
|
||||
@@ -16,8 +17,9 @@ func TestHealth(t *testing.T) {
|
||||
Environment: "test",
|
||||
ModelKey: "deepseek-v4-flash",
|
||||
}
|
||||
service := interview.NewService(interview.NewMemoryStore(), workflows.NewStubRunner())
|
||||
handler := NewHandler(cfg, service)
|
||||
memory := learnermemory.NewService(learnermemory.NewMemoryStore())
|
||||
service := interview.NewService(interview.NewMemoryStore(), workflows.NewStubRunner(), memory)
|
||||
handler := NewHandler(cfg, service, memory)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/healthz", nil)
|
||||
rec := httptest.NewRecorder()
|
||||
|
||||
27
internal/httpapi/memory.go
Normal file
27
internal/httpapi/memory.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package httpapi
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"tutor/internal/learnermemory"
|
||||
)
|
||||
|
||||
func (h Handler) getLearnerMemory(w http.ResponseWriter, r *http.Request) {
|
||||
if h.memory == nil {
|
||||
writeError(w, http.StatusNotFound, "learner memory not configured")
|
||||
return
|
||||
}
|
||||
|
||||
snapshot, err := h.memory.Snapshot(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, snapshot)
|
||||
}
|
||||
Reference in New Issue
Block a user