Phase 6: take a test (weighted sampling + question flow)
- internal/sampling: ComputeWeight (Laplace-smoothed error rate + recency
multiplier, floor 0.15) and SelectWeighted (A-Res reservoir algorithm).
10k-run statistical test verifies weak questions appear >3x more often
than mastered, and mastered questions still appear (floor exercised).
- GET/POST /test/new: source filter with live available-count JS update,
n-questions input, weighted vs uniform mode radio.
- GET /test/{id}/q/{n}: deterministic answer shuffle per (test_id,
question_id), progress bar, mobile-friendly large tap targets.
- POST /test/{id}/q/{n}: records answer + upserts stat; advances to next
question or finishes test and redirects to results stub.
- GET /test/{id}/results: stub (Phase 7 will add full review).
- Ownership enforced: all test routes 404 for wrong user.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -59,6 +59,7 @@ func main() {
|
||||
homeH := handlers.NewHomeHandler(authMgr, repo, renderer)
|
||||
uploadH := handlers.NewUploadHandler(authMgr, repo, llmClient, renderer, cfg.DataDir)
|
||||
questionH := handlers.NewQuestionHandler(authMgr, repo, renderer)
|
||||
testH := handlers.NewTestHandler(authMgr, repo, renderer)
|
||||
|
||||
r := chi.NewRouter()
|
||||
r.Use(middleware.RequestID)
|
||||
@@ -89,6 +90,11 @@ func main() {
|
||||
r.Get("/questions/{id}", questionH.Show)
|
||||
r.Post("/questions/{id}", questionH.Edit)
|
||||
r.Post("/questions/{id}/delete", questionH.Delete)
|
||||
r.Get("/test/new", testH.NewGet)
|
||||
r.Post("/test/new", testH.NewPost)
|
||||
r.Get("/test/{id}/q/{n}", testH.QuestionGet)
|
||||
r.Post("/test/{id}/q/{n}", testH.QuestionPost)
|
||||
r.Get("/test/{id}/results", testH.ResultsGet)
|
||||
})
|
||||
|
||||
srv := &http.Server{
|
||||
|
||||
Reference in New Issue
Block a user