Phase 4: upload, LLM extraction, import review flow

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jānis Kacēns
2026-05-11 13:15:04 +03:00
parent e53e7662e9
commit 5199c1fa16
10 changed files with 447 additions and 6 deletions
+9 -3
View File
@@ -22,6 +22,7 @@ import (
"qbank/internal/config"
"qbank/internal/db"
"qbank/internal/handlers"
"qbank/internal/llm"
)
func main() {
@@ -50,11 +51,13 @@ func main() {
repo := db.New(database)
authMgr := auth.NewManager(database)
renderer := handlers.NewRenderer("web/templates")
llmClient := llm.New(cfg.OpenAIAPIKey, cfg.LLMModel)
ensureIcons("web/static")
authH := handlers.NewAuthHandler(authMgr, repo, renderer)
homeH := handlers.NewHomeHandler(authMgr, renderer)
uploadH := handlers.NewUploadHandler(authMgr, repo, llmClient, renderer, cfg.DataDir)
r := chi.NewRouter()
r.Use(middleware.RequestID)
@@ -78,13 +81,17 @@ func main() {
r.Group(func(r chi.Router) {
r.Use(authMgr.RequireAuth)
r.Get("/", homeH.Handle)
r.Get("/upload", uploadH.UploadGet)
r.Post("/upload", uploadH.UploadPost)
r.Get("/import/{id}", uploadH.ImportGet)
r.Post("/import/{id}", uploadH.ImportPost)
})
srv := &http.Server{
Addr: ":" + cfg.Port,
Handler: r,
ReadTimeout: 15 * time.Second,
WriteTimeout: 30 * time.Second,
WriteTimeout: 120 * time.Second, // LLM extraction can take a while
IdleTimeout: 60 * time.Second,
}
@@ -108,7 +115,6 @@ func main() {
slog.Info("server stopped")
}
// ensureIcons generates simple solid-color PNG icons if they don't already exist.
func ensureIcons(dir string) {
for _, size := range []int{192, 512} {
path := filepath.Join(dir, fmt.Sprintf("icon-%d.png", size))
@@ -116,7 +122,7 @@ func ensureIcons(dir string) {
continue
}
img := image.NewRGBA(image.Rect(0, 0, size, size))
blue := color.RGBA{R: 37, G: 99, B: 235, A: 255} // Tailwind blue-600
blue := color.RGBA{R: 37, G: 99, B: 235, A: 255}
draw.Draw(img, img.Bounds(), &image.Uniform{C: blue}, image.Point{}, draw.Src)
f, err := os.Create(path)
if err != nil {