cake-order-tracker/main.go
2025-08-06 22:52:02 +02:00

121 lines
2.6 KiB
Go

package main
import (
"context"
"embed"
_ "embed"
"errors"
"fmt"
"log"
"net/http"
"strconv"
"github.com/Bronku/iroon/models"
"github.com/Bronku/iroon/store"
"github.com/go-chi/chi/middleware"
"github.com/go-chi/chi/v5"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
//go:embed static/*
var static embed.FS
type contextKey string
const dbContextKey = contextKey("db")
const orderContextKey = contextKey("order")
func main() {
loadConfig()
loadTemplates()
// load database
db, err := store.LoadStore(config.Database.File)
if err != nil {
log.Panic(err)
}
r := chi.NewRouter()
r.Use(middleware.RequestID)
r.Use(middleware.RealIP)
r.Use(middleware.Logger)
r.Use(middleware.Recoverer)
r.Use(middleware.Timeout(config.Server.RequestTimeout))
r.Get("/", http.RedirectHandler("/orders", http.StatusSeeOther).ServeHTTP)
r.Get("/static/", http.FileServerFS(static).ServeHTTP)
r.Route("/orders", func(r chi.Router) {
r.Use(middleware.WithValue(dbContextKey, db))
r.Route("/{orderID}", func(r chi.Router) {
r.Use(OrderCtx)
r.Get("/", getOrder)
})
})
// start server
server := &http.Server{
Handler: r,
Addr: config.Server.Addr,
ReadHeaderTimeout: config.Server.ReadHeaderTimeout,
}
err = server.ListenAndServe()
if err != nil {
log.Fatal(err)
}
}
// can't get item from context, please include it before registering route
var errNoContextValue = errors.New("no value from context")
func OrderCtx(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
db := r.Context().Value(dbContextKey).(*gorm.DB)
if db == nil {
panic(errNoContextValue)
}
var order *models.Order
var err error
orderID, err := strconv.Atoi(chi.URLParam(r, "orderID"))
if err != nil {
w.Write([]byte("url not found"))
return
}
err = db.Preload("OrderItems.Product").Preload(clause.Associations).Find(&order, orderID).Error
if err != nil {
w.Write([]byte("item not found"))
return
}
ctx := context.WithValue(r.Context(), orderContextKey, order)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
func getOrder(w http.ResponseWriter, r *http.Request) {
var db *gorm.DB
var catalogue []models.Product
var order *models.Order
var err error
db = r.Context().Value(dbContextKey).(*gorm.DB)
if db == nil {
panic(errNoContextValue)
}
err = db.Find(&catalogue).Error
if err != nil {
w.Write([]byte("no catalogue"))
return
}
order = r.Context().Value(orderContextKey).(*models.Order)
if order == nil {
panic(errNoContextValue)
}
fmt.Fprint(w, "order: ", order, "\ncatalogue: ", catalogue)
}