Initial commit

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Christoph K.
2026-03-21 15:03:55 +01:00
commit dfd66e43c6
78 changed files with 6219 additions and 0 deletions

67
backend/cmd/server/main.go Executable file
View File

@@ -0,0 +1,67 @@
package main
import (
"io/fs"
"log"
"net/http"
"krafttrainer/internal/handler"
mig "krafttrainer/internal/migrate"
"krafttrainer/internal/store"
"krafttrainer/migrations"
"krafttrainer/static"
)
func main() {
// Datenbank initialisieren
s, err := store.New("krafttrainer.db")
if err != nil {
log.Fatalf("Datenbank: %v", err)
}
defer s.Close()
// Migrationen ausführen
if err := mig.Run(s.DB(), migrations.FS); err != nil {
log.Fatalf("Migrationen: %v", err)
}
log.Println("Migrationen erfolgreich")
// HTTP-Routen
mux := http.NewServeMux()
h := handler.New(s)
h.RegisterRoutes(mux)
// SPA-Fallback: statische Dateien aus embed.FS servieren
mux.Handle("/", spaHandler(static.FS))
// Middleware-Chain und Server starten
srv := handler.Chain(mux, handler.Recoverer, handler.RequestLogger, handler.CORS)
log.Println("Server startet auf :8090")
if err := http.ListenAndServe(":8090", srv); err != nil {
log.Fatalf("Server: %v", err)
}
}
// spaHandler serviert statische Dateien und fällt auf index.html zurück (SPA-Routing).
func spaHandler(embeddedFS fs.FS) http.Handler {
fileServer := http.FileServer(http.FS(embeddedFS))
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path
if path == "/" {
path = "index.html"
} else if len(path) > 0 && path[0] == '/' {
path = path[1:]
}
f, err := embeddedFS.Open(path)
if err != nil {
// SPA-Fallback: index.html für unbekannte Pfade
r.URL.Path = "/"
} else {
f.Close()
}
fileServer.ServeHTTP(w, r)
})
}